
/*
 * 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_ws_info.h"
#include <string.h>

struct axis2_ws_info
{
    axis2_char_t *file_name;
    long last_modified_date;

    /**
     * To check whether the file is a module or a servise
     */
    int type;
};

AXIS2_EXTERN axis2_ws_info_t *AXIS2_CALL
axis2_ws_info_create_with_file_name_and_last_modified_date(
    const axutil_env_t * env,
    axis2_char_t * file_name,
    long last_modified_date)
{
    axis2_ws_info_t *ws_info = NULL;

    AXIS2_PARAM_CHECK(env->error, file_name, NULL);

    ws_info = (axis2_ws_info_t *) AXIS2_MALLOC(env->allocator,
                                               sizeof(axis2_ws_info_t));

    if (!ws_info)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    ws_info->file_name = NULL;
    ws_info->last_modified_date = 0;
    ws_info->type = 0;

    ws_info->file_name = axutil_strdup(env, file_name);
    if (!ws_info->file_name)
    {
        axis2_ws_info_free(ws_info, env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    ws_info->last_modified_date = last_modified_date;

    return ws_info;
}

AXIS2_EXTERN axis2_ws_info_t *AXIS2_CALL
axis2_ws_info_create_with_file_name_and_last_modified_date_and_type(
    const axutil_env_t * env,
    axis2_char_t * file_name,
    long last_modified_date,
    int type)
{
    axis2_ws_info_t *ws_info = NULL;

    AXIS2_PARAM_CHECK(env->error, file_name, NULL);

    ws_info = (axis2_ws_info_t *)
        axis2_ws_info_create_with_file_name_and_last_modified_date(env,
                                                                   file_name,
                                                                   last_modified_date);
    if (!ws_info)
    {
        axis2_ws_info_free(ws_info, env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    ws_info->type = type;
    return ws_info;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_ws_info_free(
    axis2_ws_info_t * ws_info,
    const axutil_env_t * env)
{
    if (ws_info->file_name)
    {
        AXIS2_FREE(env->allocator, ws_info->file_name);
    }

    if (ws_info)
    {
        AXIS2_FREE(env->allocator, ws_info);
    }

    return;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axis2_ws_info_get_file_name(
    const axis2_ws_info_t * ws_info,
    const axutil_env_t * env)
{
    return ws_info->file_name;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_ws_info_set_file_name(
    axis2_ws_info_t * ws_info,
    const axutil_env_t * env,
    axis2_char_t * file_name)
{
    AXIS2_PARAM_CHECK(env->error, file_name, AXIS2_FAILURE);

    if (ws_info->file_name)
    {
        AXIS2_FREE(env->allocator, ws_info->file_name);
        ws_info->file_name = NULL;
    }
    ws_info->file_name = file_name;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN long AXIS2_CALL
axis2_ws_info_get_last_modified_date(
    const axis2_ws_info_t * ws_info,
    const axutil_env_t * env)
{
    return ws_info->last_modified_date;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_ws_info_set_last_modified_date(
    axis2_ws_info_t * ws_info,
    const axutil_env_t * env,
    long last_modified_date)
{
    ws_info->last_modified_date = last_modified_date;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN int AXIS2_CALL
axis2_ws_info_get_type(
    const axis2_ws_info_t * ws_info,
    const axutil_env_t * env)
{
    return ws_info->type;
}

