1270 lines
38 KiB
C
1270 lines
38 KiB
C
/* $Id$
|
|
*
|
|
* Lasso - A free implementation of the Liberty Alliance specifications.
|
|
*
|
|
* Copyright (C) 2004-2007 Entr'ouvert
|
|
* http://lasso.entrouvert.org
|
|
*
|
|
* Authors: See AUTHORS file in top-level directory.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/**
|
|
* SECTION:data_service
|
|
* @short_description: ID-WSF Data Service profile
|
|
*
|
|
* DataService allows Attribute Consumers (WSC) to request an Attribute Provider (WSP) to get
|
|
* or modify data about users with their consent.
|
|
*
|
|
* Following up on #LassoDiscovery first example, it created a @service object,
|
|
* this is a #LassoDataService instance. This example continues from that step
|
|
* and retrieves the name of the principal:
|
|
*
|
|
* <informalexample>
|
|
* <programlisting>
|
|
* char *soap_answer; // SOAP answer from data service
|
|
* xmlNode *principal_name; // libxml2 xmlNode with the principal name
|
|
*
|
|
* service = lasso_discovery_get_service(discovery);
|
|
* lasso_data_service_init_query(service, "/pp:PP/pp:InformalName", NULL);
|
|
* lasso_data_service_build_request_msg(service);
|
|
*
|
|
* // service must perform SOAP call to LASSO_WSF_PROFILE(service)->msg_url
|
|
* // the SOAP message is LASSO_WSF_PROFILE(service)->msg_body. The answer
|
|
* // is stored in char* soap_answer;
|
|
*
|
|
* lasso_data_service_process_query_response_msg(service, soap_answer);
|
|
* principal_name = lasso_data_service_get_answer(service, "/pp:PP/pp:InformalName");
|
|
*
|
|
* // app should probably then use xmlNodeGetContent libxml2 function to get
|
|
* // access to node content.
|
|
* </programlisting>
|
|
* </informalexample>
|
|
*
|
|
*/
|
|
|
|
#include "../xml/private.h"
|
|
#include "../utils.h"
|
|
#include <libxml/xpath.h>
|
|
#include <libxml/xpathInternals.h>
|
|
|
|
#include "discovery.h"
|
|
#include "data_service.h"
|
|
#include "../xml/idwsf_strings.h"
|
|
#include "../xml/dst_query.h"
|
|
#include "../xml/dst_query_response.h"
|
|
#include "../xml/dst_modify.h"
|
|
#include "../xml/dst_modify_response.h"
|
|
#include "../xml/soap_binding_correlation.h"
|
|
#include "../xml/soap-1.1/soap_fault.h"
|
|
#include "../xml/is_redirect_request.h"
|
|
|
|
#include <xmlsec/xmltree.h>
|
|
#include <xmlsec/xmldsig.h>
|
|
#include <xmlsec/templates.h>
|
|
#include <xmlsec/crypto.h>
|
|
#include "wsf_profile_private.h"
|
|
|
|
extern GHashTable *dst_services_by_prefix; /* cf xml/xml.c */
|
|
|
|
static void lasso_register_idwsf_xpath_namespaces(xmlXPathContext *xpathCtx);
|
|
static gint lasso_data_service_process_query_msg(LassoDataService *service,
|
|
LassoDstQuery *query);
|
|
static gint lasso_data_service_process_modify_msg(LassoDataService *service,
|
|
LassoDstModify *modify);
|
|
static gint lasso_data_service_validate_query_request(LassoDataService *service, xmlNode *data);
|
|
static gint lasso_data_service_apply_queries(LassoDataService *service,
|
|
LassoDstQueryResponse *query_response, GList *queries, xmlNode *data);
|
|
static gint lasso_data_service_apply_query(LassoDataService *service,
|
|
LassoDstQueryResponse *query_response, xmlXPathContext *xpathCtx,
|
|
LassoDstQueryItem *item);
|
|
static gint lasso_data_service_validate_modify_request(LassoDataService *service, xmlNode **data);
|
|
static gint lasso_data_service_apply_modifications(LassoDstModify *modify,
|
|
LassoDstModifyResponse *modify_response, GList *modifications,
|
|
xmlNode **resource_data);
|
|
static gint lasso_data_service_apply_modification(LassoDstModify *modify,
|
|
LassoDstModification *modification, LassoDstModifyResponse *modify_response,
|
|
xmlNode **resource_data);
|
|
|
|
struct _LassoDataServicePrivate {
|
|
xmlNode *resource_data;
|
|
LassoDiscoResourceID *ResourceID;
|
|
LassoDiscoResourceID *EncryptedResourceID;
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
/* public methods */
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
* lasso_data_service_init_query
|
|
* @service: a #LassoDataService
|
|
* @select: resource selection string (typically a XPath query)
|
|
* @item_id: (allow-none): query item identifier (optional)
|
|
* @security_mech_id: (allow-none): a security mechanism id
|
|
*
|
|
* Initializes a new dst:Query request, asking for element @select (with optional itemID set to
|
|
* @item_id). @item_id may be NULL only if the query won't contain other query items. You must
|
|
* follow this constraint, it will not be checked.
|
|
*
|
|
* If both @select and @item_id are NULL, only a skeleton request is created and calls to
|
|
* lasso_data_service_add_query_item() will need to be done.
|
|
*
|
|
* Return value: 0 on success; or a negative value otherwise.
|
|
**/
|
|
gint
|
|
lasso_data_service_init_query(LassoDataService *service, const char *select,
|
|
const char *item_id, const char *security_mech_id)
|
|
{
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
LassoDstQuery *query = NULL;
|
|
LassoDiscoResourceOffering *offering = NULL;
|
|
gint rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
wsf_profile = &service->parent;
|
|
|
|
/* 1. build the message content */
|
|
if (select) {
|
|
query = lasso_dst_query_new(lasso_dst_query_item_new(select, item_id));
|
|
} else {
|
|
query = lasso_dst_query_new(NULL);
|
|
}
|
|
offering = lasso_wsf_profile_get_resource_offering(wsf_profile);
|
|
if (! LASSO_IS_DISCO_RESOURCE_OFFERING(offering))
|
|
goto cleanup;
|
|
lasso_assign_string(query->hrefServiceType, offering->ServiceInstance->ServiceType);
|
|
lasso_assign_new_string(query->prefixServiceType, lasso_get_prefix_for_dst_service_href(
|
|
query->hrefServiceType));
|
|
goto_cleanup_if_fail_with_rc (query->prefixServiceType != NULL,
|
|
LASSO_DATA_SERVICE_ERROR_UNREGISTERED_DST);
|
|
lasso_wsf_profile_helper_assign_resource_id(query, offering);
|
|
|
|
/* 2. build the envelope */
|
|
rc = lasso_wsf_profile_init_soap_request(wsf_profile, &query->parent);
|
|
if (rc)
|
|
goto cleanup;
|
|
|
|
/* 3. set the security mechanism */
|
|
rc = lasso_wsf_profile_set_security_mech_id(wsf_profile, security_mech_id);
|
|
|
|
cleanup:
|
|
lasso_release_gobject(query);
|
|
lasso_release_gobject(offering);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_add_query_item:
|
|
* @service: a #LassoDataService
|
|
* @select: resource selection string (typically a XPath query)
|
|
* @item_id: query item identifier
|
|
*
|
|
* Adds a dst:QueryItem to the current dst:Query request. If there are already query item in the
|
|
* request and @itemId is NULL, the call will fail.
|
|
*
|
|
* Return value: 0 if sucessfull, an error code otherwise.
|
|
**/
|
|
gint
|
|
lasso_data_service_add_query_item(LassoDataService *service,
|
|
const char *select, const char *item_id)
|
|
{
|
|
LassoWsfProfile *wsf_profile;
|
|
LassoDstQuery *query = NULL;
|
|
int rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
wsf_profile = &service->parent;
|
|
|
|
lasso_return_val_if_invalid_param(DST_QUERY, wsf_profile->request,
|
|
LASSO_PROFILE_ERROR_MISSING_REQUEST);
|
|
query = (LassoDstQuery*)wsf_profile->request;
|
|
|
|
/** Check that we can add a new item */
|
|
if (query->QueryItem && (
|
|
(query->QueryItem->data &&
|
|
(! LASSO_IS_DST_QUERY_ITEM(query->QueryItem->data) ||
|
|
LASSO_DST_QUERY_ITEM(query->QueryItem->data)->itemID == NULL)) ||
|
|
(item_id == NULL))) {
|
|
return LASSO_DATA_SERVICE_ERROR_CANNOT_ADD_ITEM;
|
|
}
|
|
|
|
lasso_list_add_new_gobject(query->QueryItem, lasso_dst_query_item_new(select, item_id));
|
|
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_get_query_item:
|
|
* @service: a #LassoDataService
|
|
* @select: the select string of the query item to found
|
|
* @item_id: the item id of the query item to found
|
|
* @output:(transfer none): a #LassoDstQueryItem handle to store the result object, its reference count is not
|
|
* incremented.
|
|
*
|
|
* Look up the first query item in the current request matching the given criteria, @select or
|
|
* @item_id. At least one of the criteria must be present for the call to succeed.
|
|
*
|
|
* Return value: 0 if successful, an error code otherwise.
|
|
*/
|
|
gint
|
|
lasso_data_service_get_query_item(LassoDataService *service,
|
|
const char *select, const char *item_id, LassoDstQueryItem **output)
|
|
{
|
|
LassoDstQuery *query = NULL;
|
|
GList *query_items = NULL;
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
gint rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
g_return_val_if_fail(select || item_id, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
wsf_profile = &service->parent;
|
|
lasso_extract_node_or_fail(query, wsf_profile->request, DST_QUERY, LASSO_PROFILE_ERROR_MISSING_REQUEST);
|
|
lasso_foreach(query_items, query->QueryItem)
|
|
{
|
|
LassoDstQueryItem *query_item = NULL;
|
|
lasso_extract_node_or_fail(query_item, query_items->data, DST_QUERY_ITEM, LASSO_ERROR_CAST_FAILED);
|
|
if ((select && lasso_strisequal(select,query_item->Select)) ||
|
|
(item_id && lasso_strisequal(item_id,query_item->itemID)))
|
|
{
|
|
if (output) {
|
|
lasso_assign_new_gobject(*output, query_item);
|
|
}
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_process_query_msg:
|
|
* @service: a #LassoDataService
|
|
* @message: the dst query message
|
|
*
|
|
* Processes a dst:Query message. Rebuilds a request object from the message
|
|
* and extracts ResourceID.
|
|
*
|
|
* Return value: 0 on success; or a negative value otherwise.
|
|
**/
|
|
static gint
|
|
lasso_data_service_process_query_msg(LassoDataService *service, LassoDstQuery *query)
|
|
{
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
LassoDstQueryResponse *query_response = NULL;
|
|
gchar *service_type = NULL;
|
|
int rc = 0;
|
|
|
|
wsf_profile = &service->parent;
|
|
|
|
lasso_assign_string(service_type, query->hrefServiceType);
|
|
|
|
lasso_wsf_profile_helper_assign_resource_id(service->private_data, query);
|
|
query_response = lasso_dst_query_response_new(lasso_utility_status_new(LASSO_DST_STATUS_CODE_OK));
|
|
query_response->prefixServiceType = g_strdup(query->prefixServiceType);
|
|
query_response->hrefServiceType = g_strdup(query->hrefServiceType);
|
|
|
|
rc = lasso_wsf_profile_init_soap_response(wsf_profile, LASSO_NODE(query_response));
|
|
lasso_release_gobject(query_response);
|
|
return rc;
|
|
}
|
|
|
|
|
|
/**
|
|
* lasso_data_service_build_response_msg:
|
|
* @service: a #LassoDataService
|
|
*
|
|
* Builds a dst:QueryResponse message.
|
|
*
|
|
* Return value: 0 on success; or a negative value otherwise.
|
|
**/
|
|
gint
|
|
lasso_data_service_build_response_msg(LassoDataService *service)
|
|
{
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
return lasso_wsf_profile_build_soap_response_msg(&service->parent);
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_get_answers:
|
|
* @service: a #LassoDataService object.
|
|
* @output:(transfer full)(allow-none)(element-type xmlNode): an xmlNode** pointer where to put the xmlNode* of the result
|
|
*
|
|
* Get all the xmlNode content of the first Data element of the QueryResponse message.
|
|
*
|
|
* Return value: 0 if sucessful, an error code otherwise.
|
|
*/
|
|
gint
|
|
lasso_data_service_get_answers(LassoDataService *service, GList **output)
|
|
{
|
|
LassoDstQueryResponse *query_response = NULL;
|
|
LassoDstData *data = NULL;
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
GList *datas = NULL;
|
|
int rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
wsf_profile = &service->parent;
|
|
lasso_extract_node_or_fail(query_response, wsf_profile->request, DST_QUERY_RESPONSE,
|
|
LASSO_PROFILE_ERROR_MISSING_REQUEST);
|
|
|
|
datas = query_response->Data;
|
|
|
|
if (datas) {
|
|
lasso_extract_node_or_fail(data, datas->data, DST_DATA,
|
|
LASSO_ERROR_CAST_FAILED);
|
|
}
|
|
|
|
if (data) {
|
|
if (output) {
|
|
GList *data_content = data->any;
|
|
lasso_release_list_of_xml_node(*output);
|
|
for (;data_content; data_content = g_list_next(data_content)) {
|
|
lasso_list_add_xml_node(*output, data_content->data);
|
|
}
|
|
}
|
|
} else {
|
|
rc = LASSO_DST_ERROR_NO_DATA;
|
|
}
|
|
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
/**
|
|
* lasso_data_service_get_answer:
|
|
* @service: a #LassoDataService object.
|
|
* @output: (out): an xmlNode** pointer where to put the xmlNode* of the result
|
|
*
|
|
* Get the first xmlNode of the first Data element of the QueryResponse message.
|
|
*
|
|
* Return value: 0 if sucessful, an error code otherwise.
|
|
*/
|
|
gint
|
|
lasso_data_service_get_answer(LassoDataService *service, xmlNode **output)
|
|
{
|
|
LassoDstQueryResponse *query_response = NULL;
|
|
LassoDstData *data = NULL;
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
GList *datas = NULL;
|
|
int rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
wsf_profile = &service->parent;
|
|
lasso_extract_node_or_fail(query_response, wsf_profile->response, DST_QUERY_RESPONSE,
|
|
LASSO_PROFILE_ERROR_MISSING_RESPONSE);
|
|
|
|
datas = query_response->Data;
|
|
|
|
if (datas) {
|
|
lasso_extract_node_or_fail(data, datas->data, DST_DATA,
|
|
LASSO_ERROR_CAST_FAILED);
|
|
}
|
|
|
|
if (data) {
|
|
if (output) {
|
|
xmlNode *first_element = NULL;
|
|
if (data->any) {
|
|
first_element = data->any->data;
|
|
}
|
|
lasso_assign_xml_node(*output, first_element);
|
|
}
|
|
} else {
|
|
rc = LASSO_DST_ERROR_NO_DATA;
|
|
}
|
|
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_get_answers_by_select:
|
|
* @service: a #LassoDataService
|
|
* @select: resource selection string (typically a XPath query)
|
|
* @output: (allow-none) (element-type xmlNode): a GList** to store a GList* containing the result, it must be freed.
|
|
*
|
|
* Returns the answers for the specified @select request.
|
|
*
|
|
* Return value: 0 if successful, an error code otheriwse
|
|
*
|
|
**/
|
|
gint
|
|
lasso_data_service_get_answers_by_select(LassoDataService *service, const char *select, GList **output)
|
|
{
|
|
LassoDstQuery *query = NULL;
|
|
LassoDstQueryResponse *query_response = NULL;
|
|
LassoDstData *data = NULL;
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
LassoDstQueryItem *query_item = NULL;
|
|
GList *iter = NULL;
|
|
GList *datas = NULL;
|
|
int rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
lasso_null_param(select);
|
|
wsf_profile = &service->parent;
|
|
lasso_extract_node_or_fail(query, wsf_profile->request, DST_QUERY,
|
|
LASSO_PROFILE_ERROR_MISSING_REQUEST);
|
|
lasso_extract_node_or_fail(query_response, wsf_profile->response, DST_QUERY_RESPONSE,
|
|
LASSO_PROFILE_ERROR_MISSING_RESPONSE);
|
|
|
|
iter = query->QueryItem;
|
|
datas = query_response->Data;
|
|
|
|
/* one query, no need for itemID, data is the first one, or absent */
|
|
if (iter && iter->next == NULL) {
|
|
lasso_extract_node_or_fail(query_item, iter->data, DST_QUERY_ITEM,
|
|
LASSO_ERROR_CAST_FAILED);
|
|
|
|
if (datas) {
|
|
lasso_extract_node_or_fail(data, datas->data, DST_DATA,
|
|
LASSO_ERROR_CAST_FAILED);
|
|
if (lasso_strisnotequal(select,query_item->Select)) {
|
|
data = NULL;
|
|
rc = LASSO_DST_ERROR_QUERY_NOT_FOUND;
|
|
}
|
|
} else {
|
|
rc = LASSO_DST_ERROR_NO_DATA;
|
|
}
|
|
/* many queries */
|
|
} else {
|
|
/* lookup select in query to get itemId, then get data with itemIdRef */
|
|
while (iter) {
|
|
lasso_extract_node_or_fail(query_item, iter->data, DST_QUERY_ITEM,
|
|
LASSO_ERROR_CAST_FAILED);
|
|
if (lasso_strisequal(query_item->Select,select)) {
|
|
break;
|
|
}
|
|
query_item = NULL;
|
|
iter = g_list_next(iter);
|
|
}
|
|
if (query_item && ! query_item->itemID) {
|
|
goto_cleanup_with_rc(LASSO_DST_ERROR_MALFORMED_QUERY);
|
|
}
|
|
|
|
while (datas) {
|
|
lasso_extract_node_or_fail(data, datas->data, DST_DATA,
|
|
LASSO_ERROR_CAST_FAILED);
|
|
if (lasso_strisequal(data->itemIDRef,query_item->itemID)) {
|
|
break;
|
|
}
|
|
data = NULL;
|
|
datas = g_list_next(datas);
|
|
}
|
|
}
|
|
|
|
if (data) {
|
|
if (output) {
|
|
GList *data_content = data->any;
|
|
lasso_release_list_of_xml_node(*output);
|
|
for (;data_content; data_content = g_list_next(data_content)) {
|
|
lasso_list_add_xml_node(*output, data_content->data);
|
|
}
|
|
}
|
|
} else {
|
|
rc = LASSO_DST_ERROR_NO_DATA;
|
|
}
|
|
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_get_answers_by_item_id:
|
|
* @service: a #LassoDataService
|
|
* @item_id: query item identifier
|
|
* @output: (allow-none) (element-type xmlNode): a GList** to store a GList* containing the result, it must be freed.
|
|
*
|
|
* Returns the answers for the specified @itemID request.
|
|
*
|
|
* Return value: 0 if successful, an error code otherwise
|
|
*
|
|
**/
|
|
gint
|
|
lasso_data_service_get_answers_by_item_id(LassoDataService *service, const char *item_id, GList **output)
|
|
{
|
|
LassoDstQueryResponse *query_response = NULL;
|
|
LassoDstData *data = NULL;
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
GList *datas = NULL;
|
|
int rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
lasso_null_param(select);
|
|
wsf_profile = &service->parent;
|
|
lasso_extract_node_or_fail(query_response, wsf_profile->request, DST_QUERY_RESPONSE,
|
|
LASSO_PROFILE_ERROR_MISSING_REQUEST);
|
|
|
|
datas = query_response->Data;
|
|
while (datas) {
|
|
lasso_extract_node_or_fail(data, datas->data, DST_DATA, LASSO_ERROR_CAST_FAILED);
|
|
if (lasso_strisequal(data->itemIDRef,item_id)) {
|
|
break;
|
|
}
|
|
data = NULL;
|
|
datas = g_list_next(datas);
|
|
}
|
|
|
|
if (data) {
|
|
if (output) {
|
|
GList *data_content = data->any;
|
|
lasso_release_list_of_xml_node(*output);
|
|
for (;data_content; data_content = g_list_next(data_content)) {
|
|
lasso_list_add_xml_node(*output, data_content->data);
|
|
}
|
|
}
|
|
} else {
|
|
rc = LASSO_DST_ERROR_NO_DATA;
|
|
}
|
|
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_process_query_response_msg:
|
|
* @service: a #LassoDataService
|
|
* @message: the dst query response message
|
|
*
|
|
* Processes a dst:Query message. Rebuilds a request object from the message
|
|
* and extracts ResourcedID.
|
|
*
|
|
* Return value: 0 on success; or a negative value otherwise.
|
|
**/
|
|
gint
|
|
lasso_data_service_process_query_response_msg(LassoDataService *service,
|
|
const char *message)
|
|
{
|
|
int rc = 0;
|
|
|
|
rc = lasso_wsf_profile_process_soap_response_msg(LASSO_WSF_PROFILE(service), message);
|
|
if (! rc && ! LASSO_IS_DST_QUERY_RESPONSE(service->parent.response)) {
|
|
rc = LASSO_PROFILE_ERROR_MISSING_RESPONSE;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_init_modify:
|
|
* @service: a #LassoDataService object
|
|
* @security_mech_id: (allow-none): a security mechanism id
|
|
*
|
|
* Initialize a Data Service Template Modify request using a command to select some data, and an XML
|
|
* fragment to replace the selected data.
|
|
*
|
|
* Return value: 0 if successful, an error code otherwise.
|
|
*/
|
|
gint
|
|
lasso_data_service_init_modify(LassoDataService *service, const char *security_mech_id)
|
|
{
|
|
LassoDiscoResourceOffering *offering = NULL;
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
LassoDstModify *modify = NULL;
|
|
gint rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
lasso_null_param(service);
|
|
wsf_profile = &service->parent;
|
|
|
|
/* 1. build the message content */
|
|
modify = lasso_dst_modify_new();
|
|
|
|
offering = lasso_wsf_profile_get_resource_offering(wsf_profile);
|
|
goto_cleanup_if_fail_with_rc (LASSO_IS_DISCO_RESOURCE_OFFERING(offering), LASSO_PROFILE_ERROR_MISSING_RESOURCE_OFFERING);
|
|
goto_cleanup_if_fail_with_rc (offering->ServiceInstance != NULL &&
|
|
offering->ServiceInstance->ServiceType != NULL,
|
|
LASSO_PROFILE_ERROR_MISSING_SERVICE_TYPE);
|
|
lasso_assign_string(modify->hrefServiceType, offering->ServiceInstance->ServiceType);
|
|
lasso_assign_new_string(modify->prefixServiceType, lasso_get_prefix_for_dst_service_href(
|
|
modify->hrefServiceType));
|
|
goto_cleanup_if_fail_with_rc (modify->prefixServiceType != NULL, LASSO_DATA_SERVICE_ERROR_UNREGISTERED_DST);
|
|
lasso_wsf_profile_helper_assign_resource_id(modify, offering);
|
|
|
|
/* 2. build the envelope */
|
|
rc = lasso_wsf_profile_init_soap_request(wsf_profile, &modify->parent);
|
|
if (rc)
|
|
goto cleanup;
|
|
|
|
/* 3. set the security mechanism */
|
|
rc = lasso_wsf_profile_set_security_mech_id(wsf_profile, security_mech_id);
|
|
|
|
cleanup:
|
|
lasso_release_gobject(modify);
|
|
lasso_release_gobject(offering);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_add_modification:
|
|
* @service: a #LassoDataService object
|
|
* @select: a selector string
|
|
* @xmlData: (allow-none): optional NewData content
|
|
* @overrideAllowed: (allow-none)(default FALSE):whether to permit delete or replace of existings
|
|
* @notChangedSince: (allow-none): if not NULL, give the time (as a local time_t value) of the last known
|
|
* modification to the datas, it is used to permit secure concurrent accesses.
|
|
* @output: (out): a #LassoDstModification** pointer where to put the #LassoDstModification of the result
|
|
*
|
|
* Add a new modification to the current modify request. If overrideAllowed is FALSE, xmlData must
|
|
* absolutely be present. Refer to the ID-WSF DST 1.0 specification for the semantic of the created
|
|
* message.
|
|
*
|
|
* Return value: 0 if successful and the new modification object in *output, an error code
|
|
* otherwise.
|
|
*/
|
|
gint
|
|
lasso_data_service_add_modification(LassoDataService *service, const gchar *select,
|
|
xmlNode *xmlData, gboolean overrideAllowed, time_t *notChangedSince,
|
|
LassoDstModification **output)
|
|
{
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
LassoDstModification *modification = NULL;
|
|
LassoDstNewData *newData = NULL;
|
|
LassoDstModify *modify = NULL;
|
|
gint rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
lasso_null_param(select);
|
|
|
|
wsf_profile = &service->parent;
|
|
lasso_extract_node_or_fail(modify, wsf_profile->request, DST_MODIFY,
|
|
LASSO_ERROR_CAST_FAILED);
|
|
|
|
modification = lasso_dst_modification_new(select);
|
|
newData = lasso_dst_new_data_new();
|
|
lasso_release_list_of_xml_node(newData->any);
|
|
lasso_list_add_xml_node(newData->any, xmlData);
|
|
lasso_assign_new_gobject(modification->NewData, newData);
|
|
lasso_list_add_new_gobject(modify->Modification,
|
|
modification);
|
|
modification->overrideAllowed = overrideAllowed;
|
|
if (notChangedSince) {
|
|
lasso_assign_new_string(modification->notChangedSince,
|
|
lasso_time_to_iso_8601_gmt(*notChangedSince));
|
|
}
|
|
|
|
if (*output) {
|
|
lasso_assign_gobject(*output, modification);
|
|
}
|
|
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
static gint
|
|
lasso_data_service_apply_modification(LassoDstModify *modify, LassoDstModification *modification, LassoDstModifyResponse *modify_response,
|
|
xmlNode **resource_data)
|
|
{
|
|
gint rc = 0;
|
|
xmlXPathObject *xpathObj = NULL;
|
|
gint xpath_error_code = 0;
|
|
char *failure_code = NULL;
|
|
LassoDstNewData *NewData = NULL;
|
|
xmlNode *cur_data = NULL;
|
|
xmlDoc *doc = NULL;
|
|
xmlXPathContext *xpathCtx = NULL;
|
|
GList *node_to_free = NULL;
|
|
gboolean overrideAllowed = modification->overrideAllowed;
|
|
|
|
if (LASSO_IS_DST_NEW_DATA(modification->NewData)) {
|
|
NewData = modification->NewData;
|
|
}
|
|
|
|
if (! modification->Select) {
|
|
failure_code = LASSO_DST_STATUS_CODE_MISSING_SELECT;
|
|
goto failure;
|
|
}
|
|
|
|
if ((! NewData || ! NewData->any) && ! overrideAllowed) {
|
|
failure_code = LASSO_DST_STATUS_CODE_MISSING_NEW_DATA_ELEMENT;
|
|
goto failure;
|
|
}
|
|
|
|
lasso_assign_xml_node(cur_data, *resource_data);
|
|
doc = xmlNewDoc((xmlChar*)"1.0");
|
|
xmlDocSetRootElement(doc, cur_data);
|
|
xpathCtx = xmlXPathNewContext(doc);
|
|
lasso_register_idwsf_xpath_namespaces(xpathCtx);
|
|
|
|
/* register namespace of the query */
|
|
xmlXPathRegisterNs(xpathCtx, BAD_CAST(modify->prefixServiceType), BAD_CAST(modify->hrefServiceType));
|
|
if (lasso_eval_xpath_expression(xpathCtx, modification->Select, &xpathObj, &xpath_error_code)) {
|
|
if (xpathObj && xpathObj->type == XPATH_NODESET) {
|
|
if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval) || (xpathObj->nodesetval->nodeNr > 1 && NewData))
|
|
{
|
|
failure_code = "too few or too much targets";
|
|
goto failure;
|
|
}
|
|
if (NewData) {
|
|
xmlNode *target = xpathObj->nodesetval->nodeTab[0];
|
|
GList *new_nodes = NewData->any;
|
|
|
|
if (target == cur_data && overrideAllowed){
|
|
if (new_nodes->next) {
|
|
failure_code = "cannot replace root node by multiple nodes";
|
|
goto failure;
|
|
}
|
|
xmlDocSetRootElement(doc,
|
|
xmlCopyNode((xmlNode*)new_nodes->data,
|
|
1));
|
|
lasso_list_add_xml_node(node_to_free, target);
|
|
} else {
|
|
while (new_nodes) {
|
|
xmlNode *new_data = NULL;
|
|
lasso_assign_xml_node(new_data, (xmlNode*)new_nodes->data);
|
|
if (overrideAllowed)
|
|
xmlAddNextSibling(target, new_data);
|
|
else
|
|
xmlAddChild(target, new_data);
|
|
new_nodes = g_list_next(new_nodes);
|
|
}
|
|
if (overrideAllowed) {
|
|
xmlUnlinkNode(target);
|
|
lasso_list_add_xml_node(node_to_free, target);
|
|
}
|
|
}
|
|
} else {
|
|
int i;
|
|
for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) {
|
|
xmlNode *target = xpathObj->nodesetval->nodeTab[i];
|
|
g_assert(overrideAllowed);
|
|
xmlUnlinkNode(target);
|
|
lasso_list_add_xml_node(node_to_free, target);
|
|
}
|
|
}
|
|
} else {
|
|
failure_code = LASSO_DST_STATUS_CODE_INVALID_SELECT;
|
|
goto failure;
|
|
}
|
|
|
|
}
|
|
lasso_assign_xml_node(*resource_data, xmlDocGetRootElement(doc));
|
|
goto cleanup;
|
|
|
|
failure:
|
|
lasso_wsf_profile_helper_set_status(modify_response, LASSO_DST_STATUS_CODE_FAILED);
|
|
lasso_wsf_profile_helper_set_status(modify_response->Status, failure_code);
|
|
rc = LASSO_DST_ERROR_MODIFY_FAILED;
|
|
|
|
cleanup:
|
|
lasso_release_xpath_object(xpathObj);
|
|
lasso_release_xpath_context(xpathCtx);
|
|
g_list_foreach(node_to_free, (GFunc)xmlFreeNode, NULL);
|
|
lasso_release_doc(doc);
|
|
lasso_release_list(node_to_free);
|
|
return rc;
|
|
}
|
|
|
|
static gint
|
|
lasso_data_service_apply_modifications(LassoDstModify *modify,
|
|
LassoDstModifyResponse *modify_response, GList *modifications,
|
|
xmlNode **resource_data)
|
|
{
|
|
gint rc = 0;
|
|
|
|
/* 1. check modifications */
|
|
if (modifications && modifications->next) {
|
|
lasso_foreach_full_begin(LassoDstModification*, modification, i, modifications)
|
|
{
|
|
if (! LASSO_IS_DST_MODIFICATION(modification) ||
|
|
! modification->id)
|
|
{
|
|
lasso_wsf_profile_helper_set_status(modify_response,
|
|
LASSO_DST_STATUS_CODE_FAILED);
|
|
lasso_wsf_profile_helper_set_status(modify_response->Status,
|
|
"id expected");
|
|
goto_cleanup_with_rc(LASSO_DST_ERROR_QUERY_FAILED);
|
|
}
|
|
}
|
|
lasso_foreach_full_end()
|
|
}
|
|
/* 2. setup workbench */
|
|
|
|
lasso_foreach_full_begin(LassoDstModification*, modification, i, modifications)
|
|
{
|
|
rc = lasso_data_service_apply_modification(modify, modification, modify_response,
|
|
resource_data);
|
|
// First error, stop
|
|
if (rc) {
|
|
goto cleanup;
|
|
}
|
|
}
|
|
lasso_foreach_full_end()
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
/* Internal implementation for processing query request messages */
|
|
static gint
|
|
lasso_data_service_validate_query_request(LassoDataService *service, xmlNode *data)
|
|
{
|
|
LassoWsfProfile *wsf_profile = &service->parent;
|
|
LassoDstQuery *query = NULL;
|
|
LassoDstQueryResponse *query_response = NULL;
|
|
gint rc = 0;
|
|
|
|
/* already checked by lasso_data_service_validate_request */
|
|
query = (LassoDstQuery*)wsf_profile->request;
|
|
lasso_extract_node_or_fail(query_response, wsf_profile->response, DST_QUERY_RESPONSE, LASSO_PROFILE_ERROR_MISSING_RESPONSE);
|
|
|
|
rc = lasso_data_service_apply_queries(service, query_response, query->QueryItem, data);
|
|
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
/* Internal implementation for processing modify request messages */
|
|
static gint
|
|
lasso_data_service_validate_modify_request(LassoDataService *service, xmlNode **data)
|
|
{
|
|
LassoWsfProfile *wsf_profile = &service->parent;
|
|
LassoDstModify *modify = NULL;
|
|
LassoDstModifyResponse *modify_response = NULL;
|
|
gint rc = 0;
|
|
|
|
/* already checked in lasso_data_service_validate_request */
|
|
modify = (LassoDstModify*)wsf_profile->request;
|
|
lasso_extract_node_or_fail(modify_response, service->parent.response, DST_MODIFY_RESPONSE,
|
|
LASSO_PROFILE_ERROR_MISSING_RESPONSE);
|
|
|
|
rc = lasso_data_service_apply_modifications(modify, modify_response, modify->Modification, data);
|
|
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
gint
|
|
lasso_data_service_validate_request(LassoDataService *service)
|
|
{
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
xmlNode *resource_data = NULL;
|
|
gint rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
wsf_profile = &service->parent;
|
|
g_return_val_if_fail(service->private_data, LASSO_PARAM_ERROR_NON_INITIALIZED_OBJECT);
|
|
resource_data = service->private_data->resource_data;
|
|
if (! resource_data) {
|
|
rc = LASSO_DST_ERROR_MISSING_SERVICE_DATA;
|
|
goto cleanup;
|
|
}
|
|
|
|
if (! LASSO_IS_NODE(wsf_profile->request)) {
|
|
rc = LASSO_PROFILE_ERROR_INVALID_REQUEST;
|
|
goto cleanup;
|
|
} else {
|
|
if (LASSO_IS_DST_QUERY(wsf_profile->request)) {
|
|
rc = lasso_data_service_validate_query_request(service, service->private_data->resource_data);
|
|
} else if (LASSO_IS_DST_MODIFY(wsf_profile->request)) {
|
|
rc = lasso_data_service_validate_modify_request(service, &service->private_data->resource_data);
|
|
} else {
|
|
rc = LASSO_PROFILE_ERROR_INVALID_REQUEST;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
gint
|
|
lasso_data_service_build_modify_response_msg(LassoDataService *service)
|
|
{
|
|
return lasso_data_service_build_response_msg(service);
|
|
}
|
|
|
|
gint
|
|
lasso_data_service_build_query_response_msg(LassoDataService *service)
|
|
{
|
|
return lasso_data_service_build_response_msg(service);
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_process_modify_msg:
|
|
* @service: a #LassoDataService object
|
|
* @modify_soap_msg: the SOAP request string
|
|
* @security_mech_id: the security mechanism to apply
|
|
*
|
|
* Parse the given request message, and initialize needed structures.
|
|
*
|
|
* Return value: 0 if successful, an error code otherwise.
|
|
*/
|
|
static gint
|
|
lasso_data_service_process_modify_msg(LassoDataService *service, LassoDstModify *modify)
|
|
{
|
|
LassoDstModifyResponse *modify_response = NULL;
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
int rc = 0;
|
|
|
|
wsf_profile = &service->parent;
|
|
|
|
lasso_wsf_profile_helper_assign_resource_id(service->private_data, modify);
|
|
modify_response = lasso_dst_modify_response_new(lasso_utility_status_new(LASSO_DST_STATUS_CODE_OK));
|
|
lasso_assign_string(modify_response->prefixServiceType, modify->prefixServiceType);
|
|
lasso_assign_string(modify_response->hrefServiceType, modify->hrefServiceType);
|
|
rc = lasso_wsf_profile_init_soap_response(wsf_profile, LASSO_NODE(modify_response));
|
|
lasso_release_gobject(modify_response);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_process_modify_response_msg
|
|
* @service: a #LassoDataService
|
|
* @soap_msg: the SOAP message
|
|
*
|
|
* Process a modify response message.
|
|
*
|
|
* Return value: 0 on success; or a negative value otherwise.
|
|
**/
|
|
gint
|
|
lasso_data_service_process_modify_response_msg(LassoDataService *service, const gchar *soap_msg)
|
|
{
|
|
int rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
lasso_null_param(soap_msg);
|
|
|
|
rc = lasso_wsf_profile_process_soap_response_msg(&service->parent, soap_msg);
|
|
|
|
if ( rc == 0 && ! LASSO_IS_DST_MODIFY_RESPONSE(service->parent.response)) {
|
|
rc = LASSO_PROFILE_ERROR_MISSING_RESPONSE;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* private methods */
|
|
/*****************************************************************************/
|
|
|
|
static LassoNodeClass *parent_class = NULL;
|
|
|
|
static void
|
|
register_xpath_namespace(gchar *prefix, gchar *href, xmlXPathContext *xpathCtx)
|
|
{
|
|
xmlXPathRegisterNs(xpathCtx, (xmlChar*)prefix, (xmlChar*)href);
|
|
}
|
|
|
|
static void
|
|
lasso_register_idwsf_xpath_namespaces(xmlXPathContext *xpathCtx)
|
|
{
|
|
xmlXPathRegisterNs(xpathCtx, (xmlChar*)LASSO_PP10_PREFIX,
|
|
(xmlChar*)LASSO_PP10_HREF);
|
|
xmlXPathRegisterNs(xpathCtx, (xmlChar*)LASSO_EP_PREFIX,
|
|
(xmlChar*)LASSO_EP_HREF);
|
|
if (dst_services_by_prefix == NULL)
|
|
return;
|
|
g_hash_table_foreach(dst_services_by_prefix,
|
|
(GHFunc)register_xpath_namespace, xpathCtx);
|
|
}
|
|
|
|
static gint
|
|
lasso_data_service_apply_query(LassoDataService *service, LassoDstQueryResponse *query_response, xmlXPathContext *xpathCtx, LassoDstQueryItem *item)
|
|
{
|
|
gint rc = 0;
|
|
xmlXPathObject *xpathObj = NULL;
|
|
gint xpath_error_code = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
lasso_bad_param(DST_QUERY_RESPONSE, query_response);
|
|
lasso_bad_param(DST_QUERY_ITEM, item);
|
|
|
|
if (! item->Select) {
|
|
lasso_wsf_profile_helper_set_status(query_response, LASSO_DST_STATUS_CODE_FAILED);
|
|
lasso_wsf_profile_helper_set_status(query_response->Status, LASSO_DST_STATUS_CODE_MISSING_SELECT);
|
|
goto_cleanup_with_rc(LASSO_DST_ERROR_QUERY_FAILED);
|
|
}
|
|
|
|
if (lasso_eval_xpath_expression(xpathCtx, item->Select, &xpathObj, &xpath_error_code)) {
|
|
LassoDstData *data = NULL;
|
|
|
|
/* Found zero or more node answers */
|
|
if (xpathObj && xpathObj->type == XPATH_NODESET){
|
|
int i = 0;
|
|
|
|
if (xpathObj->nodesetval && xpathObj->nodesetval->nodeNr) {
|
|
data = lasso_dst_data_new();
|
|
}
|
|
|
|
for (i = 0; xpathObj->nodesetval && i < xpathObj->nodesetval->nodeNr;
|
|
i++) {
|
|
lasso_list_add_xml_node(data->any,
|
|
xpathObj->nodesetval->nodeTab[i]);
|
|
}
|
|
/* Found other kind of answers, convert to string */
|
|
} else {
|
|
xmlChar *str;
|
|
|
|
data = lasso_dst_data_new();
|
|
str = xmlXPathCastToString(xpathObj);
|
|
lasso_list_add_xml_node(data->any, xmlNewText(str));
|
|
lasso_release_xml_string(str);
|
|
}
|
|
if (data) {
|
|
lasso_assign_string(data->itemIDRef, item->itemID);
|
|
lasso_list_add_gobject(query_response->Data, data);
|
|
}
|
|
lasso_release_gobject(data);
|
|
} else {
|
|
char *code = g_strdup_printf("LIBXML_XPATH_ERROR_%d", xpath_error_code);
|
|
|
|
lasso_wsf_profile_helper_set_status(query_response, LASSO_DST_STATUS_CODE_FAILED);
|
|
lasso_wsf_profile_helper_set_status(query_response->Status, LASSO_DST_STATUS_CODE_INVALID_SELECT);
|
|
lasso_wsf_profile_helper_set_status(query_response->Status->Status, code);
|
|
lasso_release_string(code);
|
|
goto_cleanup_with_rc(1);
|
|
}
|
|
|
|
cleanup:
|
|
lasso_release_xpath_object(xpathObj);
|
|
return rc;
|
|
}
|
|
|
|
static gint
|
|
lasso_data_service_apply_queries(LassoDataService *service, LassoDstQueryResponse *query_response, GList *queries, xmlNode *data)
|
|
{
|
|
gint rc = 0;
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
xmlDoc *doc = NULL;
|
|
xmlXPathContext *xpathCtx = NULL;
|
|
GList *query = NULL;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
g_return_val_if_fail(service->private_data, LASSO_PARAM_ERROR_NON_INITIALIZED_OBJECT);
|
|
wsf_profile = &service->parent;
|
|
|
|
/* 1. Check query */
|
|
if (queries && queries->next) {
|
|
GList *q = queries;
|
|
while (q) {
|
|
if (! LASSO_IS_DST_QUERY_ITEM(q->data) || !
|
|
LASSO_DST_QUERY_ITEM(q->data)->itemID) {
|
|
lasso_wsf_profile_helper_set_status(query_response,
|
|
LASSO_DST_STATUS_CODE_FAILED);
|
|
lasso_wsf_profile_helper_set_status(query_response->Status,
|
|
"itemID expected");
|
|
goto_cleanup_with_rc(LASSO_DST_ERROR_QUERY_FAILED);
|
|
}
|
|
q = g_list_next(q);
|
|
}
|
|
}
|
|
|
|
/* 1. Setup workbench */
|
|
doc = xmlNewDoc((xmlChar*)"1.0");
|
|
xmlDocSetRootElement(doc, data);
|
|
xpathCtx = xmlXPathNewContext(doc);
|
|
lasso_register_idwsf_xpath_namespaces(xpathCtx);
|
|
|
|
lasso_foreach (query, queries) {
|
|
LassoDstQueryItem *item = query->data;
|
|
|
|
goto_cleanup_if_fail_with_rc(lasso_data_service_apply_query(service, query_response,
|
|
xpathCtx, item) == 0, query_response->Data ?
|
|
LASSO_DST_ERROR_QUERY_PARTIALLY_FAILED :
|
|
LASSO_DST_ERROR_QUERY_FAILED);
|
|
}
|
|
|
|
cleanup:
|
|
xmlUnlinkNode(service->private_data->resource_data);
|
|
xmlSetTreeDoc(service->private_data->resource_data, NULL);
|
|
lasso_release_xpath_context(xpathCtx);
|
|
lasso_release_doc(doc);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_process_request_msg:
|
|
* @service: a #LassoDataService object
|
|
* @message: a C string containing the SOAP request
|
|
* @security_mech_id:(allow-none): a C string describing the required security mechanism or NULL
|
|
*
|
|
* Return value: 0 if successfull, an error code otherwise.
|
|
*/
|
|
gint
|
|
lasso_data_service_process_request_msg(LassoDataService *service,
|
|
const char *message, const char *security_mech_id)
|
|
{
|
|
LassoWsfProfile *wsf_profile = NULL;
|
|
LassoNode *request = NULL;
|
|
int rc = 0;
|
|
|
|
lasso_bad_param(DATA_SERVICE, service);
|
|
lasso_null_param(message);
|
|
wsf_profile = &service->parent;
|
|
|
|
rc = lasso_wsf_profile_process_soap_request_msg(wsf_profile, message, security_mech_id);
|
|
goto_cleanup_if_fail(! rc);
|
|
request = wsf_profile->request;
|
|
if (LASSO_IS_DST_QUERY(request)) {
|
|
rc = lasso_data_service_process_query_msg(service, (LassoDstQuery*)request);
|
|
} else if (LASSO_IS_DST_MODIFY(wsf_profile->request)) {
|
|
rc = lasso_data_service_process_modify_msg(service, (LassoDstModify*)request);
|
|
} else {
|
|
rc = LASSO_PROFILE_ERROR_INVALID_REQUEST;
|
|
}
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* overrided parent class methods */
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
dispose(GObject *object)
|
|
{
|
|
LassoDataService *service = LASSO_DATA_SERVICE(object);
|
|
|
|
lasso_release_xml_node(service->private_data->resource_data);
|
|
lasso_release_gobject(service->private_data->ResourceID);
|
|
lasso_release_gobject(service->private_data->EncryptedResourceID);
|
|
|
|
G_OBJECT_CLASS(parent_class)->dispose(object);
|
|
}
|
|
|
|
static void
|
|
finalize(GObject *object)
|
|
{
|
|
lasso_release(((LassoDataService*)object)->private_data);
|
|
|
|
G_OBJECT_CLASS(parent_class)->finalize(object);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* instance and class init functions */
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
instance_init(LassoDataService *service)
|
|
{
|
|
service->private_data = g_new0(LassoDataServicePrivate, 1);
|
|
}
|
|
|
|
static void
|
|
class_init(LassoDataServiceClass *klass, void *unused G_GNUC_UNUSED)
|
|
{
|
|
parent_class = g_type_class_peek_parent(klass);
|
|
|
|
G_OBJECT_CLASS(klass)->dispose = dispose;
|
|
G_OBJECT_CLASS(klass)->finalize = finalize;
|
|
}
|
|
|
|
GType
|
|
lasso_data_service_get_type()
|
|
{
|
|
static GType this_type = 0;
|
|
|
|
if (!this_type) {
|
|
static const GTypeInfo this_info = {
|
|
sizeof(LassoDataServiceClass),
|
|
NULL,
|
|
NULL,
|
|
(GClassInitFunc) class_init,
|
|
NULL,
|
|
NULL,
|
|
sizeof(LassoDataService),
|
|
0,
|
|
(GInstanceInitFunc) instance_init,
|
|
NULL
|
|
};
|
|
|
|
this_type = g_type_register_static(LASSO_TYPE_WSF_PROFILE,
|
|
"LassoDataService", &this_info, 0);
|
|
}
|
|
return this_type;
|
|
}
|
|
|
|
|
|
/**
|
|
* lasso_data_service_new:
|
|
* @server: the #LassoServer
|
|
*
|
|
* Creates a new #LassoDataService.
|
|
*
|
|
* Return value: a newly created #LassoDataService object; or NULL if an
|
|
* error occured.
|
|
**/
|
|
LassoDataService*
|
|
lasso_data_service_new(LassoServer *server)
|
|
{
|
|
LassoDataService *service;
|
|
|
|
g_return_val_if_fail(LASSO_IS_SERVER(server), NULL);
|
|
|
|
service = g_object_new(LASSO_TYPE_DATA_SERVICE, NULL);
|
|
LASSO_WSF_PROFILE(service)->server = g_object_ref(server);
|
|
|
|
return service;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_new_full:
|
|
* @server: the #LassoServer
|
|
* @offering: the #LassoDiscoResourceOffering
|
|
*
|
|
* Creates a new #LassoDataService.
|
|
*
|
|
* Return value: a newly created #LassoDataService object; or NULL if an error occured.
|
|
**/
|
|
LassoDataService*
|
|
lasso_data_service_new_full(LassoServer *server, LassoDiscoResourceOffering *offering)
|
|
{
|
|
LassoDataService *service = lasso_data_service_new(server);
|
|
|
|
g_return_val_if_fail(LASSO_IS_DISCO_RESOURCE_OFFERING(offering), NULL);
|
|
|
|
if (service == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
lasso_wsf_profile_set_resource_offering(&service->parent, offering);
|
|
|
|
return service;
|
|
}
|
|
|
|
/**
|
|
* lasso_data_service_set_resource_data:
|
|
* @service: a #LassoDataService object
|
|
* @resource_data: (allow-none): an xmlnode representing the resource data of the service
|
|
*
|
|
* Set the resource data content.
|
|
*/
|
|
void
|
|
lasso_data_service_set_resource_data(LassoDataService *service, const xmlNode *resource_data)
|
|
{
|
|
lasso_assign_xml_node(service->private_data->resource_data, (xmlNode*)resource_data);
|
|
}
|
|
|
|
|
|
/**
|
|
* lasso_data_service_get_resource_data:
|
|
* @service: a #LassoDataService object
|
|
*
|
|
* Return the XML resrouce data in this data service.
|
|
*
|
|
* Return value:(transfer full)(allow-none): a newly allocated #xmlNode or NULL.
|
|
*/
|
|
xmlNode *
|
|
lasso_data_service_get_resource_data(LassoDataService *service)
|
|
{
|
|
xmlNode *rv = NULL;
|
|
|
|
lasso_assign_xml_node(rv, service->private_data->resource_data);
|
|
|
|
return rv;
|
|
}
|