
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef AXIS2_ENDPOINT_REF_H
#define AXIS2_ENDPOINT_REF_H

/**
 * @defgroup axis2_endpoint_ref endpoint reference
 * @ingroup axis2_addr
 * endpoint reference represent an endpoint address in WS-Addressing.
 * In addition to the endpoint address, it also encapsulates meta data,
 * reference attributes and the service hosted at the given endpoint.
 * In addition to the addressing related implementation, the endpoint reference
 * struct is used across core code-base to represent endpoints.
 * @{
 */

/**
 * @file axis2_endpoint_ref.h
 */

#include <axis2_defines.h>
#include <axutil_env.h>
#include <axis2_const.h>
#include <axutil_array_list.h>
#include <axis2_any_content_type.h>
#include <axis2_svc_name.h>
#include <axiom_node.h>
#include <axiom_attribute.h>

#ifdef __cplusplus
extern "C"
{
#endif

    /** Type name for struct axis2_endpoint_ref */
    typedef struct axis2_endpoint_ref axis2_endpoint_ref_t;

    /**
     * Creates endpoint reference struct.
     * @param env pointer to environment struct
     * @param address endpoint address string 
     * @return pointer to newly created endpoint reference
     */
    AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL
    axis2_endpoint_ref_create(
        const axutil_env_t * env,
        const axis2_char_t * address);

    /**
     * Frees the endpoint_ref given as a void pointer. This method would cast the 
     * void parameter to an endpoint_ref pointer and then call free method.
     * @param endpoint_ref pointer to endpoint_ref as a void pointer
     * @param env pointer to environment struct
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    void AXIS2_CALL
    axis2_endpoint_ref_free_void_arg(
        void *endpoint_ref,
        const axutil_env_t * env);

    /**
     * Gets endpoint address. Address URI identifies the endpoint. 
     * This may be a network address or a logical address.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @return endpoint address string
     */
    AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
    axis2_endpoint_ref_get_address(
        const axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env);

    /**
     * Sets endpoint address. Address URI identifies the endpoint. 
     * This may be a network address or a logical address.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @param address address string
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_endpoint_ref_set_address(
        axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env,
        const axis2_char_t * address);

    /**
     * Gets interface QName. QName represents the primary portType of 
     * the endpoint being conveyed.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @return pointer to interface QName, returns a reference, not a cloned
     * copy
     */
    AXIS2_EXTERN const axutil_qname_t *AXIS2_CALL
    axis2_endpoint_ref_get_interface_qname(
        const axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env);

    /**
     * Sets interface QName. QName represents the primary portType of 
     * the endpoint being conveyed.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @param interface_qname pointer to interface QName, this method creates
     * a clone of the QName
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_endpoint_ref_set_interface_qname(
        axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env,
        const axutil_qname_t * interface_qname);

    /**
     * Gets reference parameter list. A reference may contain a number 
     * of individual parameters which are associated with the endpoint 
     * to facilitate a particular interaction. Reference parameters 
     * are element information items that are named by QName and are 
     * required to properly interact with the endpoint. 
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @return pointer to array list containing all reference parameters,
     * returns a reference, not a cloned copy 
     */
    AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
    axis2_endpoint_ref_get_ref_param_list(
        const axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env);

    /**
     * Gets the list of metadata. An endpoint can have different associated 
     * metadata such as WSDL, XML Schema, and WS-Policy policies.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @return pointer to array list containing metadata, returns a 
     * reference, not a cloned copy
     */
    AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
    axis2_endpoint_ref_get_metadata_list(
        const axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env);

    /**
     * Gets the list of reference attributes. 
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @return pointer to array list containing reference attributes, 
     * returns a reference, not a cloned copy
     */
    AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
    axis2_endpoint_ref_get_ref_attribute_list(
        const axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env);

    /**
     * Gets the list of metadata attributes.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @return pointer to array list containing metadata attributes, 
     * returns a reference, not a cloned copy
     */
    AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
    axis2_endpoint_ref_get_metadata_attribute_list(
        const axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env);

    /**
     * Gets the list of extensions. Extensions are a mechanism to allow 
     * additional elements to be specified in association with the endpoint.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @return pointer to array list containing extensions, 
     * returns a reference, not a cloned copy
     */
    AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
    axis2_endpoint_ref_get_extension_list(
        const axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env);

    /**
     * Adds a reference parameter in the form of an AXIOM node. 
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @param ref_param_node pointer to AXIOM node representing reference 
     * parameter, endpoint reference does not assume the ownership of 
     * the node 
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_endpoint_ref_add_ref_param(
        axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env,
        axiom_node_t * ref_param_node);

    /**
     * Adds metadata in the form of an AXIOM node. An endpoint can have 
     * different associated metadata such as WSDL, XML Schema and 
     * WS-Policy policies.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @param metadata_node AXIOM node representing metadata, 
     * endpoint reference does not assume the ownership of the node 
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_endpoint_ref_add_metadata(
        axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env,
        axiom_node_t * metadata_node);

    /**
     * Adds a reference attribute in the form of an AXIOM attribute.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @param attr AXIOM attribute representing reference attribute,
     * endpoint reference does not assume the ownership of the attribute
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_endpoint_ref_add_ref_attribute(
        axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env,
        axiom_attribute_t * attr);

    /**
     * Adds a meta attribute in the form of an AXIOM attribute.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @param attr AXIOM attribute representing meta attribute,
     * endpoint reference does not assume the ownership of the attribute
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_endpoint_ref_add_metadata_attribute(
        axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env,
        axiom_attribute_t * attr);

    /**
     * Adds an extension in the form of an AXIOM node.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @param extension_node pointer to AXIOM node representing extension,
     * endpoint reference does not assume the ownership of the node
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_endpoint_ref_add_extension(
        axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env,
        axiom_node_t * extension_node);

    /**
     * Gets service name. An endpoint in WS-Addressing has a QName 
     * identifying the WSDL service element that contains the definition 
     * of the endpoint being conveyed. The service name provides a link 
     * to a full description of the service endpoint.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @return pointer to service name struct, returns a reference, not 
     * a cloned copy
     */
    AXIS2_EXTERN axis2_svc_name_t *AXIS2_CALL
    axis2_endpoint_ref_get_svc_name(
        const axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env);

    /**
     * Sets service name. An endpoint in WS-Addressing has a QName 
     * identifying the WSDL service element that contains the definition 
     * of the endpoint being conveyed. The service name provides a link 
     * to a full description of the service endpoint.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @param svc_name pointer to service name struct, endpoint assumes
     * ownership of the struct
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_endpoint_ref_set_svc_name(
        axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env,
        axis2_svc_name_t * svc_name);

    /**
     * Frees endpoint reference struct.
     * @param endpoint_ref pointer to endpoint reference struct
     * @param env pointer to environment struct
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    AXIS2_EXTERN void AXIS2_CALL
    axis2_endpoint_ref_free(
        axis2_endpoint_ref_t * endpoint_ref,
        const axutil_env_t * env);

    /** @} */

#ifdef __cplusplus
}
#endif

#endif                          /* AXIS2_ENDPOINT_REF_H */
