blob: 30f0e3b285814d7d19c534ebe2cb36473125a8ee [file] [log] [blame]
/*
* 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.
*/
#include <axis2_op_ctx.h>
#include <axis2_conf_ctx.h>
#include <axis2_op.h>
#include <axis2_const.h>
#include <axutil_hash.h>
struct axis2_op_ctx
{
/** base context struct */
axis2_ctx_t *base;
/** parent of operation context is a service context instance */
struct axis2_svc_ctx *parent;
/** message context map */
axis2_msg_ctx_t *msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_MAX];
/**
* the operation of which this is a running instance. The MEP of this
* operation must be one of the 8 predefined ones in WSDL 2.0.
*/
axis2_op_t *op;
/** operation Message Exchange Pattern (MEP) */
int op_mep;
/** is complete? */
axis2_bool_t is_complete;
/** the global message_id -> op_ctx map which is stored in
* the axis2_conf_ctx. We are caching it here for faster access.
*/
axutil_hash_t *op_ctx_map;
/** op qname */
axutil_qname_t *op_qname;
/** service qname */
axutil_qname_t *svc_qname;
/* mutex to synchronize the read/write operations */
axutil_thread_mutex_t *mutex;
axis2_bool_t response_written;
axis2_bool_t is_in_use;
int ref;
};
AXIS2_EXTERN axis2_op_ctx_t *AXIS2_CALL
axis2_op_ctx_create(
const axutil_env_t * env,
axis2_op_t * op,
struct axis2_svc_ctx *svc_ctx)
{
axis2_op_ctx_t *op_ctx = NULL;
int i = 0;
op_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_op_ctx_t));
if(!op_ctx)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
return NULL;
}
op_ctx->base = NULL;
op_ctx->parent = NULL;
op_ctx->op = NULL;
op_ctx->op_mep = 0;
op_ctx->is_complete = AXIS2_FALSE;
op_ctx->is_in_use = AXIS2_FALSE;
op_ctx->op_ctx_map = NULL;
op_ctx->op_qname = NULL;
op_ctx->svc_qname = NULL;
op_ctx->response_written = AXIS2_FALSE;
op_ctx->mutex = axutil_thread_mutex_create(env->allocator, AXIS2_THREAD_MUTEX_DEFAULT);
if(!op_ctx->mutex)
{
axis2_op_ctx_free(op_ctx, env);
return NULL;
}
op_ctx->base = axis2_ctx_create(env);
if(!(op_ctx->base))
{
axis2_op_ctx_free(op_ctx, env);
return NULL;
}
if(op)
{
op_ctx->op = op;
}
for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++)
{
op_ctx->msg_ctx_array[i] = NULL;
}
if(op_ctx->op)
{
op_ctx->op_qname = (axutil_qname_t *)axis2_op_get_qname(op_ctx->op, env);
op_ctx->op_mep = axis2_op_get_axis_specific_mep_const(op_ctx->op, env);
}
axis2_op_ctx_set_parent(op_ctx, env, svc_ctx);
op_ctx->ref = 1;
return op_ctx;
}
AXIS2_EXTERN axis2_ctx_t *AXIS2_CALL
axis2_op_ctx_get_base(
const axis2_op_ctx_t * op_ctx,
const axutil_env_t * env)
{
return op_ctx->base;
}
AXIS2_EXTERN void AXIS2_CALL
axis2_op_ctx_free(
struct axis2_op_ctx *op_ctx,
const axutil_env_t * env)
{
int i = 0;
if(--(op_ctx->ref) > 0)
{
return;
}
if(op_ctx->is_in_use)
{
return;
}
if(op_ctx->base)
{
axis2_ctx_free(op_ctx->base, env);
}
for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++)
{
if(op_ctx->msg_ctx_array[i])
{
axis2_msg_ctx_free(op_ctx->msg_ctx_array[i], env);
op_ctx->msg_ctx_array[i] = NULL;
}
}
if(op_ctx->mutex)
{
axutil_thread_mutex_destroy(op_ctx->mutex);
}
AXIS2_FREE(env->allocator, op_ctx);
return;
}
AXIS2_EXTERN void AXIS2_CALL
axis2_op_ctx_destroy_mutex(
struct axis2_op_ctx *op_ctx,
const axutil_env_t * env)
{
if(op_ctx->mutex)
{
axutil_thread_mutex_destroy(op_ctx->mutex);
op_ctx->mutex = NULL;
}
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_init(
struct axis2_op_ctx *op_ctx,
const axutil_env_t * env,
struct axis2_conf *conf)
{
int i = 0;
if(op_ctx->op_qname && op_ctx->svc_qname)
{
axis2_svc_t *svc = NULL;
axis2_char_t *svc_name = NULL;
svc_name = axutil_qname_get_localpart(op_ctx->svc_qname, env);
if(svc_name)
{
svc = axis2_conf_get_svc(conf, env, svc_name);
if(svc)
{
op_ctx->op = axis2_svc_get_op_with_qname(svc, env, op_ctx->op_qname);
}
}
}
for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++)
{
if(op_ctx->msg_ctx_array[i])
{
axis2_msg_ctx_init(op_ctx->msg_ctx_array[i], env, conf);
}
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_op_t *AXIS2_CALL
axis2_op_ctx_get_op(
const axis2_op_ctx_t * op_ctx,
const axutil_env_t * env)
{
return op_ctx->op;
}
AXIS2_EXTERN struct axis2_svc_ctx *AXIS2_CALL
axis2_op_ctx_get_parent(
const axis2_op_ctx_t * op_ctx,
const axutil_env_t * env)
{
return op_ctx->parent;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_add_msg_ctx(
struct axis2_op_ctx * op_ctx,
const axutil_env_t * env,
axis2_msg_ctx_t * msg_ctx)
{
axis2_msg_ctx_t *out_msg_ctx = NULL;
axis2_msg_ctx_t *in_msg_ctx = NULL;
axutil_thread_mutex_lock(op_ctx->mutex);
out_msg_ctx = op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_OUT];
in_msg_ctx = op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_IN];
if(out_msg_ctx && in_msg_ctx)
{
axutil_thread_mutex_unlock(op_ctx->mutex);
return AXIS2_FAILURE;
}
if(!out_msg_ctx)
{
op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_OUT] = msg_ctx;
}
else
{
op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_IN] = msg_ctx;
}
axutil_thread_mutex_unlock(op_ctx->mutex);
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL
axis2_op_ctx_get_msg_ctx(
const axis2_op_ctx_t * op_ctx,
const axutil_env_t * env,
const axis2_wsdl_msg_labels_t message_id)
{
axutil_thread_mutex_lock(op_ctx->mutex);
if(op_ctx->msg_ctx_array)
{
axis2_msg_ctx_t *rv = NULL;
rv = op_ctx->msg_ctx_array[message_id];
axutil_thread_mutex_unlock(op_ctx->mutex);
return rv;
}
axutil_thread_mutex_unlock(op_ctx->mutex);
return NULL;
}
AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_op_ctx_get_is_complete(
const axis2_op_ctx_t * op_ctx,
const axutil_env_t * env)
{
return op_ctx->is_complete;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_set_complete(
struct axis2_op_ctx * op_ctx,
const axutil_env_t * env,
axis2_bool_t is_complete)
{
op_ctx->is_complete = is_complete;
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_op_ctx_is_in_use(
const axis2_op_ctx_t * op_ctx,
const axutil_env_t * env)
{
return op_ctx->is_in_use;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_set_in_use(
struct axis2_op_ctx * op_ctx,
const axutil_env_t * env,
axis2_bool_t is_in_use)
{
op_ctx->is_in_use = is_in_use;
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_cleanup(
struct axis2_op_ctx * op_ctx,
const axutil_env_t * env)
{
int i = 0;
for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++)
{
if(op_ctx->msg_ctx_array[i])
{
axis2_msg_ctx_free(op_ctx->msg_ctx_array[i], env);
op_ctx->msg_ctx_array[i] = NULL;
}
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_set_parent(
struct axis2_op_ctx * op_ctx,
const axutil_env_t * env,
struct axis2_svc_ctx * svc_ctx)
{
if(svc_ctx)
{
op_ctx->parent = svc_ctx;
}
if(op_ctx->parent) /* that is if there is a service context associated */
{
axis2_conf_ctx_t *conf_ctx = NULL;
conf_ctx = axis2_svc_ctx_get_conf_ctx(op_ctx->parent, env);
if(conf_ctx)
{
op_ctx->op_ctx_map = axis2_conf_ctx_get_op_ctx_map(conf_ctx, env);
}
op_ctx->svc_qname = (axutil_qname_t *)axis2_svc_get_qname(axis2_svc_ctx_get_svc(
op_ctx->parent, env), env);
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_msg_ctx_t **AXIS2_CALL
axis2_op_ctx_get_msg_ctx_map(
const axis2_op_ctx_t * op_ctx,
const axutil_env_t * env)
{
return (axis2_msg_ctx_t **)(op_ctx->msg_ctx_array);
}
AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_op_ctx_get_response_written(
const axis2_op_ctx_t * op_ctx,
const axutil_env_t * env)
{
if(op_ctx)
return op_ctx->response_written;
else
return AXIS2_FALSE;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_set_response_written(
axis2_op_ctx_t * op_ctx,
const axutil_env_t * env,
const axis2_bool_t written)
{
if(op_ctx)
{
op_ctx->response_written = written;
}
else
{
return AXIS2_FAILURE;
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_increment_ref(
axis2_op_ctx_t * op_ctx,
const axutil_env_t * env)
{
op_ctx->ref++;
return AXIS2_SUCCESS;
}