1
/* $Id: idwsf2_data_service.c 3101 2007-05-30 11:40:10Z dlaniel $
3
* Lasso - A free implementation of the Liberty Alliance specifications.
5
* Copyright (C) 2004-2007 Entr'ouvert
6
* http://lasso.entrouvert.org
8
* Authors: See AUTHORS file in top-level directory.
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#include <libxml/xpath.h>
26
#include <libxml/xpathInternals.h>
28
#include <lasso/id-wsf-2.0/discovery.h>
29
#include <lasso/id-wsf-2.0/data_service.h>
31
#include <lasso/xml/id-wsf-2.0/disco_service_type.h>
32
#include <lasso/xml/id-wsf-2.0/dstref_query.h>
33
#include <lasso/xml/id-wsf-2.0/dstref_query_response.h>
34
#include <lasso/xml/id-wsf-2.0/dstref_data.h>
35
#include <lasso/xml/id-wsf-2.0/util_status.h>
36
#include <lasso/xml/id-wsf-2.0/sb2_redirect_request.h>
37
#include <lasso/xml/id-wsf-2.0/dstref_modify.h>
38
#include <lasso/xml/id-wsf-2.0/dstref_modify_item.h>
39
#include <lasso/xml/id-wsf-2.0/dstref_modify_response.h>
41
#include <lasso/xml/soap_fault.h>
43
struct _LassoIdWsf2DataServicePrivate
45
gboolean dispose_has_run;
46
LassoWsAddrEndpointReference *epr;
50
/*****************************************************************************/
52
/*****************************************************************************/
55
lasso_idwsf2_data_service_init_query(LassoIdWsf2DataService *service)
57
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
58
LassoIdWsf2DstRefQuery *query;
59
LassoWsAddrEndpointReference *epr;
62
gchar *service_type = NULL;
64
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
65
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
67
query = lasso_idwsf2_dstref_query_new();
69
if (LASSO_PROFILE(profile)->request) {
70
lasso_node_destroy(LASSO_NODE(LASSO_PROFILE(profile)->request));
72
LASSO_PROFILE(profile)->request = LASSO_NODE(query);
74
if (service == NULL || service->private_data == NULL
75
|| service->private_data->epr == NULL
76
|| service->private_data->epr->Metadata == NULL) {
77
return LASSO_PROFILE_ERROR_MISSING_ENDPOINT_REFERENCE;
80
epr = service->private_data->epr;
82
/* Get the service type from the EPR */
83
metadata_item = epr->Metadata->any;
84
for (i = g_list_first(metadata_item); i != NULL; i = g_list_next(i)) {
85
if (LASSO_IS_IDWSF2_DISCO_SERVICE_TYPE(i->data)) {
86
service_type = LASSO_IDWSF2_DISCO_SERVICE_TYPE(i->data)->content;
91
/* Set hrefServiceType and prefixServiceType in query in order to set the profile */
92
/* namespace in the request */
93
if (service_type != NULL) {
94
query->hrefServiceType = g_strdup(service_type);
95
query->prefixServiceType = lasso_get_prefix_for_idwsf2_dst_service_href(
96
query->hrefServiceType);
98
if (query->prefixServiceType == NULL) {
99
return LASSO_PROFILE_ERROR_MISSING_SERVICE_TYPE;
102
lasso_idwsf2_profile_init_soap_request(profile, LASSO_NODE(query), service_type);
104
/* Set msg_url as epr address, which is the SoapEndpoint */
105
if (epr->Address != NULL) {
106
LASSO_PROFILE(profile)->msg_url = g_strdup(epr->Address->content);
108
return LASSO_PROFILE_ERROR_MISSING_ENDPOINT_REFERENCE_ADDRESS;
115
lasso_idwsf2_data_service_add_query_item(LassoIdWsf2DataService *service, const gchar *item_xpath,
116
const gchar *item_id)
118
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
119
LassoIdWsf2DstRefQuery *query;
120
LassoIdWsf2DstRefQueryItem *item;
122
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
123
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
124
g_return_val_if_fail(item_xpath != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
125
g_return_val_if_fail(item_id != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
127
if (! LASSO_IS_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request)) {
128
return LASSO_PROFILE_ERROR_MISSING_REQUEST;
131
query = LASSO_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request);
133
item = lasso_idwsf2_dstref_query_item_new_full(item_xpath, item_id);
134
query->QueryItem = g_list_append(query->QueryItem, item);
140
lasso_idwsf2_data_service_process_query_msg(LassoIdWsf2DataService *service, const gchar *message)
142
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
143
LassoIdWsf2DstRefQuery *request = NULL;
144
LassoIdWsf2DstRefResultQuery *item = NULL;
148
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
149
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
150
g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
152
res = lasso_idwsf2_profile_process_soap_request_msg(profile, message);
154
if (! LASSO_IS_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request)) {
155
res = LASSO_PROFILE_ERROR_INVALID_SOAP_MSG;
157
request = LASSO_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request);
158
service->type = g_strdup(request->hrefServiceType);
162
/* Parse QueryItems to get a list of Xpath strings */
163
for (i = g_list_first(request->QueryItem); i != NULL; i = g_list_next(i)) {
164
item = LASSO_IDWSF2_DSTREF_RESULT_QUERY(i->data);
165
if (item->Select != NULL) {
166
service->query_items = g_list_append(
167
service->query_items, g_strdup(item->Select));
176
lasso_idwsf2_data_service_parse_query_items(LassoIdWsf2DataService *service)
178
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
179
LassoIdWsf2DstRefQuery *request;
180
LassoIdWsf2DstRefQueryResponse *response;
181
LassoIdWsf2UtilResponse *response2;
182
LassoSoapEnvelope *envelope;
184
xmlXPathContext *xpathCtx;
185
xmlXPathObject *xpathObj;
186
LassoIdWsf2DstRefQueryItem *item;
187
LassoIdWsf2DstRefResultQuery *item_result_query;
188
LassoIdWsf2DstResultQueryBase *item_result_query_base;
189
LassoIdWsf2DstRefData *data;
190
LassoIdWsf2DstRefItemData *data_item;
195
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
196
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
198
if (! LASSO_IS_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request)) {
199
return LASSO_PROFILE_ERROR_MISSING_REQUEST;
201
request = LASSO_IDWSF2_DSTREF_QUERY(LASSO_PROFILE(profile)->request);
203
if (service->data == NULL) {
204
return LASSO_DST_ERROR_MISSING_SERVICE_DATA;
207
/* Response envelope and body */
208
envelope = profile->soap_envelope_response;
209
if (envelope == NULL) {
210
return LASSO_SOAP_ERROR_MISSING_ENVELOPE;
212
response = lasso_idwsf2_dstref_query_response_new();
213
response->prefixServiceType = g_strdup(request->prefixServiceType);
214
response->hrefServiceType = g_strdup(request->hrefServiceType);
215
LASSO_PROFILE(profile)->response = LASSO_NODE(response);
216
envelope->Body->any = g_list_append(envelope->Body->any, response);
218
response2 = LASSO_IDWSF2_UTIL_RESPONSE(response);
219
/* Default is Failed, will be OK or Partial when some items are successfully parsed */
220
response2->Status = lasso_idwsf2_util_status_new();
221
response2->Status->code = g_strdup(LASSO_DST_STATUS_CODE_FAILED);
223
/* Initialise XML parsing */
224
doc = xmlNewDoc((xmlChar*)"1.0");
225
xmlDocSetRootElement(doc, service->data);
226
xpathCtx = xmlXPathNewContext(doc);
227
xmlXPathRegisterNs(xpathCtx, (xmlChar*)response->prefixServiceType,
228
(xmlChar*)response->hrefServiceType);
230
/* Parse request QueryItems and fill response Data accordingly */
231
/* XXX: needs another level, since there may be more than one <dst:Query> */
232
for (iter = g_list_first(request->QueryItem); iter != NULL; iter = g_list_next(iter)) {
234
item_result_query = LASSO_IDWSF2_DSTREF_RESULT_QUERY(item);
235
item_result_query_base = LASSO_IDWSF2_DST_RESULT_QUERY_BASE(item);
236
xpathObj = xmlXPathEvalExpression((xmlChar*)item_result_query->Select, xpathCtx);
237
if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeNr) {
238
/* XXX: assuming there is only one matching node */
239
node = xpathObj->nodesetval->nodeTab[0];
240
data = lasso_idwsf2_dstref_data_new();
241
data_item = LASSO_IDWSF2_DSTREF_ITEM_DATA(data);
242
LASSO_IDWSF2_DSTREF_APP_DATA(data_item)->any = g_list_append(
243
LASSO_IDWSF2_DSTREF_APP_DATA(data_item)->any,
244
xmlCopyNode(node, 1));
245
if (item_result_query_base->itemID != NULL) {
246
data_item->itemIDRef = g_strdup(item_result_query_base->itemID);
248
response->Data = g_list_append(response->Data, data);
249
/* Success : change status code to OK */
250
if (strcmp(response2->Status->code, LASSO_DST_STATUS_CODE_FAILED) == 0) {
251
g_free(response2->Status->code);
252
response2->Status->code = g_strdup(LASSO_DST_STATUS_CODE_OK);
254
xmlXPathFreeObject(xpathObj);
257
/* If status was OK, change it to Partial */
258
if (strcmp(response2->Status->code, LASSO_DST_STATUS_CODE_OK) == 0) {
259
g_free(response2->Status->code);
260
response2->Status->code = g_strdup(LASSO_DST_STATUS_CODE_PARTIAL);
262
res = LASSO_DST_ERROR_QUERY_FAILED;
264
if (xpathObj != NULL) {
265
xmlXPathFreeObject(xpathObj);
268
/* Stop processing at first error */
273
/* Free XML parsing objects */
274
xmlUnlinkNode(service->data);
275
xmlXPathFreeContext(xpathCtx);
278
if (res == 0 && strcmp(response2->Status->code, LASSO_DST_STATUS_CODE_FAILED) == 0) {
279
res = LASSO_DST_ERROR_QUERY_FAILED;
286
lasso_idwsf2_data_service_process_query_response_soap_fault_msg(LassoIdWsf2DataService *service,
287
const gchar *message)
289
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
290
LassoSoapFault *fault;
291
LassoIdWsf2Sb2RedirectRequest *redirect_request = NULL;
295
if (! LASSO_IS_SOAP_FAULT(LASSO_PROFILE(profile)->response)) {
296
/* Should not happen as it should be checked in caller */
300
fault = LASSO_SOAP_FAULT(LASSO_PROFILE(profile)->response);
302
if (fault->Detail == NULL || fault->Detail->any == NULL) {
303
return LASSO_SOAP_ERROR_MISSING_SOAP_FAULT_DETAIL;
306
/* Get RedirectRequest element from soap fault detail */
307
for (iter = fault->Detail->any; iter != NULL; iter = iter->next) {
308
if (LASSO_IS_IDWSF2_SB2_REDIRECT_REQUEST(iter->data) == TRUE) {
309
redirect_request = LASSO_IDWSF2_SB2_REDIRECT_REQUEST(iter->data);
314
if (redirect_request != NULL) {
315
/* This is not a failure, this exception code indicates the WSP needs to ask */
316
/* user consent to get an attribute */
317
res = LASSO_SOAP_FAULT_REDIRECT_REQUEST;
318
/* Get redirect request url */
319
service->redirect_url = g_strdup(redirect_request->redirectURL);
326
lasso_idwsf2_data_service_process_query_response_msg(LassoIdWsf2DataService *service,
327
const gchar *message)
329
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
330
LassoIdWsf2UtilResponse *response;
333
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
334
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
335
g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
337
res = lasso_idwsf2_profile_process_soap_response_msg(profile, message);
342
/* Message can be either a SoapFault or a QueryResponse */
343
if (LASSO_IS_SOAP_FAULT(LASSO_PROFILE(profile)->response)) {
344
return lasso_idwsf2_data_service_process_query_response_soap_fault_msg(
348
if (! LASSO_IS_IDWSF2_DSTREF_QUERY_RESPONSE(LASSO_PROFILE(profile)->response)) {
349
return LASSO_PROFILE_ERROR_INVALID_SOAP_MSG;
352
/* Check response status code */
353
response = LASSO_IDWSF2_UTIL_RESPONSE(LASSO_PROFILE(profile)->response);
354
if (response->Status == NULL || response->Status->code == NULL) {
355
return LASSO_PROFILE_ERROR_MISSING_STATUS_CODE;
357
if (strcmp(response->Status->code, LASSO_DST_STATUS_CODE_PARTIAL) == 0) {
358
return LASSO_DST_ERROR_QUERY_PARTIALLY_FAILED;
359
} else if (strcmp(response->Status->code, LASSO_DST_STATUS_CODE_OK) != 0) {
360
return LASSO_DST_ERROR_QUERY_FAILED;
367
lasso_idwsf2_data_service_get_attribute_node(LassoIdWsf2DataService *service, const gchar *item_id)
369
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
370
LassoIdWsf2DstRefQueryResponse *response;
371
LassoIdWsf2DstRefAppData *data = NULL;
374
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service), NULL);
376
g_return_val_if_fail(LASSO_IS_IDWSF2_DSTREF_QUERY_RESPONSE(
377
LASSO_PROFILE(profile)->response), NULL);
379
response = LASSO_IDWSF2_DSTREF_QUERY_RESPONSE(LASSO_PROFILE(profile)->response);
381
/* If no item_id is given, return the first item */
382
if (item_id == NULL && response->Data != NULL && response->Data->data != NULL) {
383
data = LASSO_IDWSF2_DSTREF_APP_DATA(response->Data->data);
384
if (data->any != NULL && data->any->data != NULL) {
385
return xmlCopyNode(data->any->data, 1);
388
if (item_id == NULL) {
392
/* Find the item which has the given item_id */
393
for (iter = g_list_first(response->Data); iter != NULL; iter = g_list_next(iter)) {
394
if (! LASSO_IS_IDWSF2_DSTREF_ITEM_DATA(iter->data)) {
397
if (strcmp(LASSO_IDWSF2_DSTREF_ITEM_DATA(iter->data)->itemIDRef, item_id) == 0) {
398
data = LASSO_IDWSF2_DSTREF_APP_DATA(iter->data);
403
if (data == NULL || data->any == NULL || data->any->data == NULL) {
408
/* XXX: there may be more than one xmlnode */
409
return xmlCopyNode(data->any->data, 1);
413
lasso_idwsf2_data_service_get_attribute_string(LassoIdWsf2DataService *service,
414
const gchar *item_id)
417
xmlChar *xml_content;
420
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service), NULL);
422
node = lasso_idwsf2_data_service_get_attribute_node(service, item_id);
423
xml_content = xmlNodeGetContent(node);
424
content = g_strdup((gchar*)xml_content);
426
xmlFree(xml_content);
433
lasso_idwsf2_data_service_init_redirect_user_for_consent(LassoIdWsf2DataService *service,
434
const gchar *redirect_url)
436
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
437
LassoSoapEnvelope *envelope;
438
LassoSoapFault *fault;
439
LassoSoapDetail *detail;
441
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
442
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
443
g_return_val_if_fail(redirect_url != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
445
/* Response envelope */
446
envelope = profile->soap_envelope_response;
447
if (envelope == NULL) {
448
return LASSO_SOAP_ERROR_MISSING_ENVELOPE;
451
/* Build soap fault node */
452
fault = lasso_soap_fault_new();
453
fault->faultcode = g_strdup(LASSO_SOAP_FAULT_CODE_SERVER);
454
fault->faultstring = g_strdup(LASSO_SOAP_FAULT_STRING_SERVER);
455
detail = lasso_soap_detail_new();
456
detail->any = g_list_append(
457
detail->any, lasso_idwsf2_sb2_redirect_request_new_full(redirect_url));
458
fault->Detail = detail;
460
/* Response envelope body */
461
envelope->Body->any = g_list_append(envelope->Body->any, fault);
467
lasso_idwsf2_data_service_init_modify(LassoIdWsf2DataService *service)
469
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
470
LassoIdWsf2DstRefModify *modify;
471
LassoWsAddrEndpointReference *epr;
472
GList *metadata_item;
474
gchar *service_type = NULL;
476
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
477
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
479
modify = lasso_idwsf2_dstref_modify_new();
481
if (LASSO_PROFILE(profile)->request) {
482
lasso_node_destroy(LASSO_NODE(LASSO_PROFILE(profile)->request));
484
LASSO_PROFILE(profile)->request = LASSO_NODE(modify);
486
if (service == NULL || service->private_data == NULL
487
|| service->private_data->epr == NULL
488
|| service->private_data->epr->Metadata == NULL) {
489
return LASSO_PROFILE_ERROR_MISSING_ENDPOINT_REFERENCE;
492
epr = service->private_data->epr;
494
/* Get the service type from the EPR */
495
metadata_item = epr->Metadata->any;
496
for (i = g_list_first(metadata_item); i != NULL; i = g_list_next(i)) {
497
if (LASSO_IS_IDWSF2_DISCO_SERVICE_TYPE(i->data)) {
498
service_type = LASSO_IDWSF2_DISCO_SERVICE_TYPE(i->data)->content;
503
/* Set hrefServiceType and prefixServiceType in query in order to set the profile */
504
/* namespace in the request */
505
if (service_type != NULL) {
506
modify->hrefServiceType = g_strdup(service_type);
507
modify->prefixServiceType = lasso_get_prefix_for_idwsf2_dst_service_href(
508
modify->hrefServiceType);
510
if (modify->prefixServiceType == NULL) {
511
return LASSO_PROFILE_ERROR_MISSING_SERVICE_TYPE;
514
lasso_idwsf2_profile_init_soap_request(profile, LASSO_NODE(modify), service_type);
516
/* Set msg_url as epr address, which is the SoapEndpoint */
517
if (epr->Address != NULL) {
518
LASSO_PROFILE(profile)->msg_url = g_strdup(epr->Address->content);
520
return LASSO_PROFILE_ERROR_MISSING_ENDPOINT_REFERENCE_ADDRESS;
526
static void set_xml_string(xmlNode **xmlnode, const char* string)
531
doc = xmlReadDoc((xmlChar*)string, NULL, NULL, XML_PARSE_NONET);
532
node = xmlDocGetRootElement(doc);
534
node = xmlCopyNode(node, 1);
539
xmlFreeNode(*xmlnode);
546
lasso_idwsf2_data_service_add_modify_item(LassoIdWsf2DataService *service, const gchar *item_xpath,
547
const gchar *item_id, const gchar *new_data, const gboolean overrideAllowed)
549
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
550
LassoIdWsf2DstRefModify *modify;
551
LassoIdWsf2DstRefModifyItem *item;
552
xmlNode *new_data_node = NULL;
554
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
555
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
556
g_return_val_if_fail(item_xpath != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
557
g_return_val_if_fail(item_id != NULL, LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
559
if (! LASSO_IS_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request)) {
560
return LASSO_PROFILE_ERROR_MISSING_REQUEST;
563
modify = LASSO_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request);
565
set_xml_string(&new_data_node, new_data);
566
item = lasso_idwsf2_dstref_modify_item_new_full(
567
item_xpath, item_id, new_data_node, overrideAllowed);
568
modify->ModifyItem = g_list_append(modify->ModifyItem, item);
574
lasso_idwsf2_data_service_process_modify_msg(LassoIdWsf2DataService *service, const gchar *message)
576
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
577
LassoIdWsf2DstRefModify *request = NULL;
580
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
581
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
582
g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
584
res = lasso_idwsf2_profile_process_soap_request_msg(profile, message);
586
if (! LASSO_IS_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request)) {
587
res = LASSO_PROFILE_ERROR_INVALID_SOAP_MSG;
589
request = LASSO_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request);
590
service->type = g_strdup(request->hrefServiceType);
597
lasso_idwsf2_data_service_parse_one_modify_item(LassoIdWsf2DstRefModifyItem *item,
598
LassoIdWsf2DstRefModifyResponse *response, xmlDoc *cur_doc, xmlXPathContext *cur_xpathCtx)
600
xmlXPathObject *cur_xpathObj;
606
return LASSO_DST_ERROR_MODIFY_FAILED;
609
/* Check NewData existence */
610
if (item->NewData == NULL || item->NewData->any == NULL
611
|| item->NewData->any->data == NULL) {
612
if (item->overrideAllowed == TRUE) {
615
return LASSO_DST_ERROR_NEW_DATA_MISSING;
618
new_node = (xmlNode*)item->NewData->any->data;
621
if (item->overrideAllowed == FALSE) {
622
/* Add the new item and add it to the current data */
623
/* FIXME : when the ancestor nodes of the new node do not */
624
/* exist either, they MUST be added */
625
xmlAddChild(xmlDocGetRootElement(cur_doc), xmlCopyNode(new_node, 1));
627
/* Modify an existing node */
628
cur_xpathObj = xmlXPathEvalExpression((xmlChar*)item->Select, cur_xpathCtx);
629
if (cur_xpathObj && cur_xpathObj->nodesetval && cur_xpathObj->nodesetval->nodeNr) {
630
/* XXX: assuming there is only one matching node */
631
cur_node = cur_xpathObj->nodesetval->nodeTab[0];
632
if (new_node != NULL) {
633
/* Replace old node with new data */
634
xmlReplaceNode(cur_node, xmlCopyNode(new_node, 1));
636
/* Remove old node as new data is empty */
637
xmlUnlinkNode(cur_node);
638
xmlFreeNode(cur_node);
641
res = LASSO_DST_ERROR_MODIFY_FAILED;
643
xmlXPathFreeObject(cur_xpathObj);
650
lasso_idwsf2_data_service_parse_modify_items(LassoIdWsf2DataService *service)
652
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
653
LassoIdWsf2DstRefModify *request;
654
LassoIdWsf2DstRefModifyResponse *response;
655
LassoIdWsf2UtilResponse *response2;
656
LassoSoapEnvelope *envelope;
658
xmlXPathContext *cur_xpathCtx;
659
LassoIdWsf2DstRefModifyItem *item;
661
LassoIdWsf2UtilStatus *secondary_status;
665
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
666
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
668
if (! LASSO_IS_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request)) {
669
return LASSO_PROFILE_ERROR_MISSING_REQUEST;
671
request = LASSO_IDWSF2_DSTREF_MODIFY(LASSO_PROFILE(profile)->request);
673
if (service->data == NULL) {
674
return LASSO_DST_ERROR_MISSING_SERVICE_DATA;
676
cur_data = xmlCopyNode(service->data, 1);
679
/* Response envelope and body */
680
envelope = profile->soap_envelope_response;
681
if (envelope == NULL) {
682
return LASSO_SOAP_ERROR_MISSING_ENVELOPE;
684
response = lasso_idwsf2_dstref_modify_response_new();
685
response->prefixServiceType = g_strdup(request->prefixServiceType);
686
response->hrefServiceType = g_strdup(request->hrefServiceType);
687
LASSO_PROFILE(profile)->response = LASSO_NODE(response);
688
envelope->Body->any = g_list_append(envelope->Body->any, response);
690
response2 = LASSO_IDWSF2_UTIL_RESPONSE(response);
691
response2->Status = lasso_idwsf2_util_status_new();
693
/* Initialise XML parsing */
694
cur_doc = xmlNewDoc((xmlChar*)"1.0");
695
xmlDocSetRootElement(cur_doc, cur_data);
696
cur_xpathCtx = xmlXPathNewContext(cur_doc);
697
xmlXPathRegisterNs(cur_xpathCtx, (xmlChar*)response->prefixServiceType,
698
(xmlChar*)response->hrefServiceType);
700
/* Parse request ModifyItems and modify user current data accordingly */
701
/* XXX: needs another level, since there may be more than one <dst:Modify> */
702
for (iter = g_list_first(request->ModifyItem); iter != NULL; iter = g_list_next(iter)) {
704
res = lasso_idwsf2_data_service_parse_one_modify_item(
705
item, response, cur_doc, cur_xpathCtx);
707
/* If one item fails, stop and roll back */
713
response2->Status->code = g_strdup(LASSO_DST_STATUS_CODE_OK);
714
/* Save new service data */
715
xmlFreeNode(service->data);
716
service->data = xmlCopyNode(cur_data, 1);
718
response2->Status->code = g_strdup(LASSO_DST_STATUS_CODE_FAILED);
719
if (res == LASSO_DST_ERROR_NEW_DATA_MISSING) {
720
secondary_status = lasso_idwsf2_util_status_new();
721
secondary_status->code = g_strdup(
722
LASSO_DST_STATUS_CODE_MISSING_NEW_DATA_ELEMENT);
723
response2->Status->Status = g_list_append(
724
response2->Status->Status, secondary_status);
728
/* Free XML parsing objects */
729
xmlXPathFreeContext(cur_xpathCtx);
736
lasso_idwsf2_data_service_process_modify_response_msg(LassoIdWsf2DataService *service,
737
const gchar *message)
739
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(service);
740
LassoIdWsf2UtilResponse *response;
743
g_return_val_if_fail(LASSO_IS_IDWSF2_DATA_SERVICE(service),
744
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
745
g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
747
res = lasso_idwsf2_profile_process_soap_response_msg(profile, message);
752
if (! LASSO_IS_IDWSF2_DSTREF_MODIFY_RESPONSE(LASSO_PROFILE(profile)->response)) {
753
return LASSO_PROFILE_ERROR_INVALID_SOAP_MSG;
756
/* Check response status code */
757
response = LASSO_IDWSF2_UTIL_RESPONSE(LASSO_PROFILE(profile)->response);
758
if (response->Status == NULL || response->Status->code == NULL) {
759
return LASSO_PROFILE_ERROR_MISSING_STATUS_CODE;
761
if (strcmp(response->Status->code, LASSO_DST_STATUS_CODE_PARTIAL) == 0) {
762
return LASSO_DST_ERROR_MODIFY_PARTIALLY_FAILED;
763
} else if (strcmp(response->Status->code, LASSO_DST_STATUS_CODE_OK) != 0) {
764
return LASSO_DST_ERROR_MODIFY_FAILED;
770
/*****************************************************************************/
771
/* private methods */
772
/*****************************************************************************/
774
static LassoNodeClass *parent_class = NULL;
776
/*****************************************************************************/
777
/* overrided parent class methods */
778
/*****************************************************************************/
781
dispose(GObject *object)
783
LassoIdWsf2DataService *service = LASSO_IDWSF2_DATA_SERVICE(object);
785
if (service->private_data->dispose_has_run == TRUE)
787
service->private_data->dispose_has_run = TRUE;
789
if (service->type != NULL) {
790
g_free(service->type);
791
service->type = NULL;
793
if (service->redirect_url != NULL) {
794
g_free(service->redirect_url);
795
service->redirect_url = NULL;
797
if (service->query_items != NULL) {
798
g_list_free(service->query_items);
799
service->query_items = NULL;
802
if (service->private_data->epr != NULL) {
803
lasso_node_destroy(LASSO_NODE(service->private_data->epr));
804
service->private_data->epr = NULL;
807
G_OBJECT_CLASS(parent_class)->dispose(object);
811
finalize(GObject *object)
813
LassoIdWsf2DataService *service = LASSO_IDWSF2_DATA_SERVICE(object);
814
g_free(service->private_data);
815
service->private_data = NULL;
816
G_OBJECT_CLASS(parent_class)->finalize(object);
820
/*****************************************************************************/
821
/* instance and class init functions */
822
/*****************************************************************************/
825
instance_init(LassoIdWsf2DataService *service)
827
service->data = NULL;
828
service->type = NULL;
829
service->redirect_url = NULL;
830
service->query_items = NULL;
831
service->private_data = g_new0(LassoIdWsf2DataServicePrivate, 1);
832
service->private_data->epr = NULL;
836
class_init(LassoIdWsf2DataServiceClass *klass)
838
parent_class = g_type_class_peek_parent(klass);
840
G_OBJECT_CLASS(klass)->dispose = dispose;
841
G_OBJECT_CLASS(klass)->finalize = finalize;
845
lasso_idwsf2_data_service_get_type()
847
static GType this_type = 0;
850
static const GTypeInfo this_info = {
851
sizeof(LassoIdWsf2DataServiceClass),
854
(GClassInitFunc) class_init,
857
sizeof(LassoIdWsf2DataService),
859
(GInstanceInitFunc) instance_init,
862
this_type = g_type_register_static(LASSO_TYPE_IDWSF2_PROFILE,
863
"LassoIdWsf2DataService", &this_info, 0);
870
* lasso_idwsf2_data_service_new:
872
* Creates a new #LassoIdWsf2DataService.
874
* Return value: a newly created #LassoIdWsf2DataService object
876
LassoIdWsf2DataService*
877
lasso_idwsf2_data_service_new(LassoServer *server)
879
LassoIdWsf2DataService *service;
881
g_return_val_if_fail(LASSO_IS_SERVER(server), NULL);
883
service = g_object_new(LASSO_TYPE_IDWSF2_DATA_SERVICE, NULL);
885
LASSO_PROFILE(service)->server = g_object_ref(server);
890
LassoIdWsf2DataService*
891
lasso_idwsf2_data_service_new_full(LassoServer *server, LassoWsAddrEndpointReference *epr)
893
LassoIdWsf2DataService *service;
895
g_return_val_if_fail(LASSO_IS_SERVER(server), NULL);
896
g_return_val_if_fail(LASSO_IS_WSA_ENDPOINT_REFERENCE(epr), NULL);
898
service = lasso_idwsf2_data_service_new(server);
900
service->private_data->epr = g_object_ref(epr);