summaryrefslogtreecommitdiffstats
path: root/src/core/context/op_ctx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/context/op_ctx.c')
-rw-r--r--src/core/context/op_ctx.c420
1 files changed, 420 insertions, 0 deletions
diff --git a/src/core/context/op_ctx.c b/src/core/context/op_ctx.c
new file mode 100644
index 0000000..30f0e3b
--- /dev/null
+++ b/src/core/context/op_ctx.c
@@ -0,0 +1,420 @@
+/*
+ * 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;
+}
+