00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <string.h>
00026 #include <libxml/parser.h>
00027 #include <libxml/catalog.h>
00028 #include <libxml/parserInternals.h>
00029 #include <libxml/xmlmemory.h>
00030 #include <libxml/SAX.h>
00031 #include <libxml/xmlerror.h>
00032 #include <libxml/uri.h>
00033 #include <libxml/hash.h>
00034
00035 #include "utils.h"
00036
00037 #include "mlview-parsing-utils.h"
00038 #include "mlview-global-settings.h"
00039 #include "mlview-file-descriptor.h"
00040
00041 static MlViewExternalSubsetDefinition * p_external_subset_def=NULL ;
00042 static gboolean p_store_external_subset_def = FALSE ;
00043 static const gint MAX_NUMBER_OF_ELEMENT_NAMES_IN_CHOICE_LIST = 256 ;
00044 extern int xmlDoValidityCheckingDefaultValue ;
00045
00046 #ifdef MLVIEW_DATA_DIR
00047 static const gchar * gv_mlview_data_dir = MLVIEW_DATA_DIR ;
00048 #else
00049 static const gchar * gv_mlview_data_dir = NULL
00050 #endif
00051
00052 #ifdef MLVIEW_XML_CATALOG_DIR_NAME
00053 static const gchar * gv_mlview_xml_catalog_dir_name = MLVIEW_XML_CATALOG_DIR_NAME ;
00054 #else
00055 static const gchar * gv_mlview_xml_catalog_dir_name = NULL ;
00056 #endif
00057
00058 typedef struct _MlViewCustomParserContext MlViewCustomParserContext ;
00059
00064 struct _MlViewCustomParserContext {
00065 xmlParserCtxt initial_context ;
00066 MlViewAppContext * mlview_app_context ;
00067 } ;
00068
00069 static MlViewCustomParserContext *
00070 mlview_custom_parser_context_new (xmlParserCtxt *a_xml_parser_ctxt,
00071 MlViewAppContext * a_mlview_app_context) ;
00072
00073 static void
00074 mlview_custom_parser_context_destroy (MlViewCustomParserContext * a_context) ;
00075
00076
00077
00078 static MlViewExternalSubsetDefinition *
00079 mlview_external_subset_definition_clone (MlViewExternalSubsetDefinition * a_ext_subs_def) ;
00080
00081 static xmlParserInput *
00082 mlview_custom_external_entity_loader (const char *URL, const char * ID,
00083 xmlParserCtxt *a_context) ;
00084
00085 static void
00086 mlview_custom_external_subset_sax_handler (void *a_ctx,
00087 const xmlChar *a_name,
00088 const xmlChar *a_external_id,
00089 const xmlChar *a_system_id) ;
00090
00091
00092 static xmlParserInput *
00093 mlview_custom_sax_resolve_entity (void *a_ctx, const xmlChar *a_public_id,
00094 const xmlChar * a_system_id) ;
00095
00096 static int
00097 load_xml_document_from_local_file (gchar * a_xml_file_name,
00098 xmlParserCtxtPtr *a_parser_context,
00099 gboolean a_store_external_subset_info,
00100 MlViewAppContext * a_app_context) ;
00101
00102 static xmlDtdPtr custom_xmlSAXParseDTD (MlViewAppContext *a_app_context, xmlSAXHandlerPtr sax,
00103 const xmlChar *ExternalID, const xmlChar *SystemID) ;
00104
00105
00106 static gboolean
00107 mlview_parsing_utils_ask_user_for_DTD_change_and_validation (MlViewAppContext *a_app_context,
00108 const gchar * a_external_id,
00109 const gchar * a_system_id,
00110 MlViewExternalSubsetDefinition ** a_external_subset_def) ;
00111
00112 static gboolean
00113 mlview_can_resolve_external_entity (MlViewAppContext * a_app_context,
00114 const xmlChar *a_external_id,
00115 const xmlChar *a_system_id) ;
00116
00117
00118 static void
00119 mlview_parsing_utils_scan_and_build_entities_list (void * a_hash_data,
00120 void * a_output_list,
00121 void * a_entity_name) ;
00122
00123 static void
00124 mlview_parsing_utils_scan_and_build_ids_list (void * a_hash_data,
00125 void * a_output_list,
00126 void * a_id_value) ;
00127
00128 static void
00129 build_required_element_content (MlViewAppContext *a_app_context,
00130 xmlElementContent * a_content,
00131 xmlNode **a_node) ;
00132
00133 static gint
00134 g_list_compare_string_elems (gchar *a_elem1, gchar *a_elem2) ;
00135
00136 static gboolean
00137 is_an_ancestor_node (xmlNode *a_ancestor, xmlNode *a_cur_node) ;
00138
00143 MlViewExternalSubsetDefinition *
00144 mlview_external_subset_definition_new (const gchar *a_root_element_name,
00145 const gchar * a_external_id,
00146 const gchar * a_system_id)
00147
00148 {
00149 MlViewExternalSubsetDefinition * result ;
00150
00151 result = g_malloc0(sizeof(MlViewExternalSubsetDefinition)) ;
00152
00153 if(a_external_id != NULL)
00154 result->external_id = g_strdup(a_external_id) ;
00155
00156 if(a_system_id != NULL)
00157 result->system_id = g_strdup(a_system_id) ;
00158
00159 if(a_root_element_name != NULL)
00160 result->root_element_name = g_strdup(a_root_element_name) ;
00161
00162 return result ;
00163 }
00164
00165
00169 static MlViewExternalSubsetDefinition *
00170 mlview_external_subset_definition_clone (MlViewExternalSubsetDefinition * a_ext_subs_def)
00171 {
00172 g_return_val_if_fail(a_ext_subs_def != NULL, NULL) ;
00173 return mlview_external_subset_definition_new (a_ext_subs_def->root_element_name,
00174 a_ext_subs_def->external_id,
00175 a_ext_subs_def->system_id) ;
00176 }
00177
00178
00183 void
00184 mlview_external_subset_definition_destroy (MlViewExternalSubsetDefinition * a_def)
00185 {
00186 g_return_if_fail (a_def != NULL) ;
00187
00188 if (a_def->external_id != NULL ) {
00189 g_free (a_def->external_id) ;
00190 a_def->external_id = NULL ;
00191 }
00192
00193 if (a_def->system_id != NULL) {
00194 g_free (a_def->system_id) ;
00195 a_def->system_id = NULL ;
00196 }
00197
00198 if (a_def->root_element_name != NULL) {
00199 g_free (a_def->root_element_name) ;
00200 a_def->root_element_name = NULL ;
00201 }
00202
00203 g_free (a_def) ;
00204 }
00205
00210 static
00211 MlViewCustomParserContext *
00212 mlview_custom_parser_context_new (xmlParserCtxt *a_xml_parser_ctxt,
00213 MlViewAppContext * a_mlview_app_context)
00214 {
00215 MlViewCustomParserContext * result=NULL ;
00216 g_return_val_if_fail (a_xml_parser_ctxt != NULL, NULL) ;
00217
00218 result = g_malloc0 (sizeof (MlViewCustomParserContext)) ;
00219 g_assert (result != NULL) ;
00220 memmove (&result->initial_context, a_xml_parser_ctxt, sizeof (xmlParserCtxt)) ;
00221 result->mlview_app_context = a_mlview_app_context ;
00222 ((xmlParserCtxt*)result)->userData = result ;
00223 return result ;
00224 }
00225
00226
00230 static void
00231 mlview_custom_parser_context_destroy (MlViewCustomParserContext * a_context)
00232 {
00233 g_return_if_fail (a_context != NULL) ;
00234 g_free (a_context) ;
00235 }
00236
00237
00248 static int
00249 load_xml_document_from_local_file (gchar * a_xml_file_name,
00250 xmlParserCtxt ** a_parser_context,
00251 gboolean a_store_external_subset_info,
00252 MlViewAppContext * a_app_context)
00253 {
00254 FILE * file_ptr ;
00255 int size = 1024, num_of_chars_read = 0, parse_status ;
00256 gchar file_buffer[size] ;
00257 MlViewCustomParserContext * custom_parser_context ;
00258 gchar * validation_is_on = NULL ;
00259 xmlDoValidityCheckingDefaultValue = 0 ;
00260
00261 if (a_app_context)
00262 validation_is_on =
00263 mlview_app_context_get_settings_value (a_app_context, MLVIEW_STG_K_IS_VALIDATION_ON) ;
00264
00265
00266 g_return_val_if_fail ( a_xml_file_name != NULL, MLVIEW_UTILS_ERR_FILE_NAME_NULL) ;
00267
00268 file_ptr = fopen (a_xml_file_name, "r") ;
00269 g_return_val_if_fail ( file_ptr != NULL,
00270 MLVIEW_UTILS_ERR_BAD_FILE ) ;
00271 num_of_chars_read = fread ( file_buffer, 1 ,4,file_ptr) ;
00272 g_return_val_if_fail ( num_of_chars_read > 0,MLVIEW_UTILS_ERR_EMPTY_FILE ) ;
00273
00274
00275
00276
00277
00278 xmlKeepBlanksDefault (0) ;
00279
00280 (*a_parser_context) =
00281 xmlCreatePushParserCtxt (NULL,NULL,
00282 file_buffer,num_of_chars_read,a_xml_file_name) ;
00283
00284
00285
00286
00287
00288
00289 custom_parser_context = mlview_custom_parser_context_new (*a_parser_context,
00290 a_app_context) ;
00291 g_return_val_if_fail (custom_parser_context != NULL,
00292 MLVIEW_UTILS_ERR) ;
00293
00294
00295 if (a_store_external_subset_info == TRUE) {
00296
00297
00298
00299
00300 ((xmlParserCtxt*)custom_parser_context)->sax->externalSubset = mlview_custom_external_subset_sax_handler ;
00301 ((xmlParserCtxt*)custom_parser_context)->sax->resolveEntity = mlview_custom_sax_resolve_entity ;
00302
00303
00304 p_store_external_subset_def = a_store_external_subset_info ;
00305 }
00306
00307
00308 xmlSetGenericErrorFunc(a_app_context, (xmlGenericErrorFunc) mlview_app_context_bufferize_error) ;
00309
00310 while ( (num_of_chars_read = fread (file_buffer,1,size,file_ptr)) >0 ) {
00311 parse_status = xmlParseChunk ((xmlParserCtxt*) custom_parser_context,
00312 file_buffer,num_of_chars_read, 0) ;
00313
00314 if (parse_status != XML_ERR_OK)
00315 break ;
00316 }
00317
00318
00319 if (parse_status == XML_ERR_OK) {
00320 parse_status =
00321 xmlParseChunk ((xmlParserCtxt*) custom_parser_context,
00322 file_buffer,num_of_chars_read,1) ;
00323 }
00324
00325
00326 xmlSetGenericErrorFunc(NULL, NULL) ;
00327
00328 if ( a_app_context && ! mlview_app_context_error_buffer_is_empty (a_app_context))
00329 mlview_app_context_display_buffered_error (a_app_context) ;
00330 else
00331 mlview_app_context_set_error_dialog_title (a_app_context, NULL) ;
00332
00333
00334 memcpy (*a_parser_context, custom_parser_context, sizeof (xmlParserCtxt)) ;
00335 mlview_custom_parser_context_destroy (custom_parser_context) ;
00336 custom_parser_context = NULL ;
00337
00338 return (parse_status == XML_ERR_OK) ? 0 : parse_status ;
00339 }
00340
00341
00347 static xmlParserInput *
00348 mlview_custom_external_entity_loader (const char *URL, const char * ID,
00349 xmlParserCtxt *a_context )
00350 {
00351 xmlParserInput * result = NULL ;
00352 xmlChar *resource = NULL ;
00353 gchar * xml_catalog_file = NULL ;
00354 xmlCatalog * xml_catalog = NULL ;
00355 gboolean can_resolve = FALSE ;
00356
00357 can_resolve =
00358 mlview_can_resolve_external_entity (((MlViewCustomParserContext*)a_context)->mlview_app_context, ID, URL) ;
00359
00360 if (can_resolve == FALSE)
00361 return NULL ;
00362
00363 if (gv_mlview_data_dir && gv_mlview_xml_catalog_dir_name) {
00364 xml_catalog_file = g_strconcat (gv_mlview_data_dir, "/",
00365 gv_mlview_xml_catalog_dir_name, "/",
00366 "catalog.xml",
00367 NULL) ;
00368 }
00369
00370 if (a_context
00371 &&((MlViewCustomParserContext*)a_context)->mlview_app_context)
00372 xml_catalog =
00373 mlview_app_context_get_xml_catalog (((MlViewCustomParserContext*)a_context)->mlview_app_context) ;
00374
00375 if (xml_catalog == NULL) {
00376 xml_catalog = xmlLoadACatalog (xml_catalog_file) ;
00377 mlview_app_context_set_xml_catalog (((MlViewCustomParserContext*)a_context)->mlview_app_context,
00378 xml_catalog) ;
00379 }
00380
00381 if (xml_catalog_file) {
00382 g_free (xml_catalog_file) ;
00383 xml_catalog_file = NULL ;
00384 }
00385
00386 if (xml_catalog == NULL) {
00387 mlview_app_context_error (((MlViewCustomParserContext*)a_context)->mlview_app_context,
00388 _("Could not load mlview xml catalog")) ;
00389 return NULL ;
00390 }
00391
00392 if (ID != NULL || URL != NULL) {
00393 resource =
00394 xmlACatalogResolve (xml_catalog, ID, URL) ;
00395 }
00396
00397 if (resource == NULL) {
00398 MlViewFileDescriptor * file_desc = NULL ;
00399 gboolean is_readable = FALSE ;
00400
00401 file_desc = mlview_file_descriptor_new (URL) ;
00402 if (!mlview_file_descriptor_is_readable (file_desc, &is_readable) && is_readable == TRUE)
00403 result = xmlNewInputFromFile (a_context, mlview_file_descriptor_get_file_path (file_desc)) ;
00404 else
00405 result = NULL ;
00406 if (file_desc)
00407 mlview_file_descriptor_destroy (file_desc) ;
00408 }else {
00409 result = xmlNewInputFromFile (a_context, resource) ;
00410 }
00411
00412 if (resource) {
00413 xmlFree (resource) ;
00414 }
00415
00416 return result ;
00417 }
00418
00419
00423 static xmlParserInput *
00424 mlview_custom_sax_resolve_entity (void *a_ctx, const xmlChar *a_public_id,
00425 const xmlChar * a_system_id)
00426 {
00427 xmlParserCtxt * parser_context = (xmlParserCtxt *) a_ctx ;
00428 xmlParserInput * result = NULL ;
00429 xmlChar *URI = NULL ;
00430 const gchar * base = NULL ;
00431
00432 if (parser_context == NULL) {
00433
00434
00435 parser_context = xmlNewParserCtxt() ;
00436 }
00437
00438 if (parser_context && (parser_context->input != NULL))
00439 base = (const char *) parser_context->input->filename ;
00440 if (base == NULL && parser_context)
00441 base = parser_context->directory ;
00442
00443 URI = xmlBuildURI (a_system_id, NULL) ;
00444 result =
00445 mlview_custom_external_entity_loader ( (const char *)URI,
00446 (const char *)a_public_id,
00447 parser_context) ;
00448 if (URI != NULL)
00449 xmlFree (URI) ;
00450
00451 return result ;
00452 }
00453
00454
00462 static gboolean
00463 mlview_can_resolve_external_entity (MlViewAppContext * a_app_context,
00464 const xmlChar *a_external_id,
00465 const xmlChar *a_system_id)
00466 {
00467 xmlCatalog * xml_catalog = NULL ;
00468 gchar * xml_catalog_file = NULL, *resource = NULL ;
00469 MlViewFileDescriptor * file_desc = NULL ;
00470 gboolean result = FALSE ;
00471
00472 g_return_val_if_fail (a_app_context != NULL, FALSE) ;
00473 g_return_val_if_fail (a_app_context != NULL, FALSE) ;
00474 g_return_val_if_fail (MLVIEW_IS_APP_CONTEXT (a_app_context), FALSE) ;
00475
00476 if (gv_mlview_data_dir && gv_mlview_xml_catalog_dir_name) {
00477 xml_catalog_file = g_strconcat (gv_mlview_data_dir, "/",
00478 gv_mlview_xml_catalog_dir_name, "/",
00479 "catalog.xml",
00480 NULL) ;
00481 }
00482
00483 xml_catalog = mlview_app_context_get_xml_catalog (a_app_context) ;
00484
00485 if (xml_catalog == NULL) {
00486 xml_catalog = xmlLoadACatalog (xml_catalog_file) ;
00487 mlview_app_context_set_xml_catalog (a_app_context, xml_catalog) ;
00488 }
00489
00490 if (xml_catalog_file) {
00491 g_free (xml_catalog_file) ;
00492 xml_catalog_file = NULL ;
00493 }
00494
00495 if (xml_catalog == NULL) {
00496 return FALSE ;
00497 }
00498
00499 resource = xmlACatalogResolve (xml_catalog, a_external_id,
00500 a_system_id) ;
00501 if (resource) {
00502 xmlFree (resource) ;
00503 return TRUE ;
00504 }
00505
00506
00507
00508
00509 file_desc = mlview_file_descriptor_new (a_system_id) ;
00510
00511 if (file_desc) {
00512 gboolean is_readable = FALSE;
00513 if (!mlview_file_descriptor_is_readable (file_desc, &is_readable) && is_readable == TRUE) {
00514 result = TRUE ;
00515 }
00516 mlview_file_descriptor_destroy (file_desc) ;
00517 file_desc = NULL ;
00518 }
00519
00520 return result ;
00521 }
00522
00536 static void
00537 mlview_custom_external_subset_sax_handler (void *a_ctx, const xmlChar *a_name,
00538 const xmlChar *a_external_id,
00539 const xmlChar *a_system_id)
00540 {
00541 MlViewCustomParserContext * custom_parser_context =
00542 (MlViewCustomParserContext*)a_ctx ;
00543 gchar * validation_is_on = NULL ;
00544
00545
00546 if (custom_parser_context
00547 && custom_parser_context->mlview_app_context) {
00548 validation_is_on =
00549 mlview_app_context_get_settings_value (custom_parser_context->mlview_app_context,
00550 MLVIEW_STG_K_IS_VALIDATION_ON) ;
00551 }
00552
00553 if (validation_is_on
00554 && (strcmp (validation_is_on, MLVIEW_STG_V_YES) == 0)
00555 && (xmlParserCtxt*)custom_parser_context)
00556 ((xmlParserCtxt*)custom_parser_context)->validate = 1 ;
00557 else
00558 ((xmlParserCtxt*)custom_parser_context)->validate = 0 ;
00559
00560
00561
00562
00563
00564 if (((xmlParserCtxt*)custom_parser_context)->validate == 1
00565 && (custom_parser_context->mlview_app_context != NULL)) {
00566 MlViewExternalSubsetDefinition * external_subset_def = NULL ;
00567 gboolean validate =
00568 mlview_parsing_utils_ask_user_for_DTD_change_and_validation (custom_parser_context->mlview_app_context,
00569 a_external_id,
00570 a_system_id,
00571 &external_subset_def) ;
00572 if (validate == FALSE)
00573 ((xmlParserCtxt*)custom_parser_context)->validate = 0 ;
00574
00575 if (validate && external_subset_def) {
00576 a_external_id = external_subset_def->external_id ;
00577 a_system_id = external_subset_def->system_id ;
00578 }
00579 }
00580
00581 if (((xmlParserCtxt*)custom_parser_context)->validate == 1) {
00582 externalSubset(a_ctx, a_name, a_external_id, a_system_id) ;
00583 if (((xmlParserCtxt*)a_ctx)->myDoc
00584 && ((xmlParserCtxt*)a_ctx)->myDoc->extSubset == NULL) {
00585 mlview_app_context_warning (custom_parser_context->mlview_app_context,
00586 _("The external DTD subset was not found. I couldn't validate the document :(\n."));
00587 }
00588 }
00589
00590
00591
00592
00593
00594 ((xmlParserCtxt*)custom_parser_context)->validate = 0 ;
00595 }
00596
00597
00598 static xmlDtdPtr
00599 custom_xmlSAXParseDTD (MlViewAppContext *a_app_context, xmlSAXHandlerPtr sax,
00600 const xmlChar *ExternalID, const xmlChar *SystemID)
00601 {
00602 xmlDtdPtr ret = NULL;
00603 xmlParserCtxtPtr ctxt;
00604 xmlParserInputPtr input = NULL;
00605 xmlCharEncoding enc;
00606 MlViewCustomParserContext * custom_parser_context = NULL ;
00607
00608 if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
00609
00610 ctxt = xmlNewParserCtxt();
00611 if (ctxt == NULL) {
00612 return(NULL);
00613 }
00614
00615
00616
00617
00618 if (sax != NULL) {
00619 if (ctxt->sax != NULL)
00620 xmlFree(ctxt->sax);
00621 ctxt->sax = sax ;
00622 }
00623
00624 custom_parser_context = mlview_custom_parser_context_new (ctxt, a_app_context) ;
00625
00626
00627
00628
00629
00630 if ((custom_parser_context->initial_context.sax != NULL) && (custom_parser_context->initial_context.sax->resolveEntity != NULL))
00631 input = custom_parser_context->initial_context.sax->resolveEntity(custom_parser_context->initial_context.userData, ExternalID, SystemID);
00632 if (input == NULL) {
00633 if (sax != NULL) custom_parser_context->initial_context.sax = NULL;
00634 mlview_custom_parser_context_destroy (custom_parser_context) ;
00635 xmlFreeParserCtxt(ctxt);
00636 return(NULL);
00637 }
00638
00639
00640
00641
00642 xmlPushInput ((xmlParserCtxt*)&custom_parser_context->initial_context, input);
00643 enc = xmlDetectCharEncoding (custom_parser_context->initial_context.input->cur, 4);
00644 xmlSwitchEncoding ((xmlParserCtxt*) &custom_parser_context->initial_context, enc);
00645
00646 if (input->filename == NULL)
00647 input->filename = (char *) xmlStrdup(SystemID);
00648 input->line = 1;
00649 input->col = 1;
00650 input->base = custom_parser_context->initial_context.input->cur;
00651 input->cur = custom_parser_context->initial_context.input->cur;
00652 input->free = NULL;
00653
00654
00655
00656
00657 custom_parser_context->initial_context.inSubset = 2;
00658 custom_parser_context->initial_context.myDoc = xmlNewDoc(BAD_CAST "1.0");
00659 custom_parser_context->initial_context.myDoc->extSubset =
00660 xmlNewDtd (custom_parser_context->initial_context.myDoc, BAD_CAST "none",
00661 ExternalID, SystemID);
00662 xmlParseExternalSubset ((xmlParserCtxt*) &custom_parser_context->initial_context, ExternalID, SystemID);
00663
00664 if (custom_parser_context->initial_context.myDoc != NULL) {
00665 if (custom_parser_context->initial_context.wellFormed) {
00666 ret = custom_parser_context->initial_context.myDoc->extSubset;
00667 custom_parser_context->initial_context.myDoc->extSubset = NULL;
00668 } else {
00669 ret = NULL;
00670 }
00671 xmlFreeDoc(custom_parser_context->initial_context.myDoc);
00672 custom_parser_context->initial_context.myDoc = NULL;
00673 }
00674
00675 if (sax != NULL) custom_parser_context->initial_context.sax = NULL;
00676 mlview_custom_parser_context_destroy (custom_parser_context) ;
00677 custom_parser_context = NULL ;
00678 xmlFreeParserCtxt (ctxt) ;
00679 ctxt = NULL ;
00680
00681 return(ret);
00682 }
00683
00691 static gboolean
00692 mlview_parsing_utils_ask_user_for_DTD_change_and_validation (MlViewAppContext *a_app_context,
00693 const gchar * a_external_id,
00694 const gchar * a_system_id,
00695 MlViewExternalSubsetDefinition ** a_external_subset_def)
00696 {
00697 GnomeDialog * dialog = NULL ;
00698 gint button ;
00699 gboolean result = TRUE, can_resolve_entity = FALSE ;
00700 GtkWidget * label = NULL ;
00701 gchar * label_str = NULL ;
00702 const gchar *public_id = NULL ;
00703 const gchar *system_id = NULL ;
00704
00705 g_return_val_if_fail (a_app_context != NULL, TRUE) ;
00706 g_return_val_if_fail (a_external_subset_def != NULL, TRUE) ;
00707
00708 public_id = (const gchar *) (a_external_id != NULL) ? a_external_id : "\"\"" ;
00709 system_id = (const gchar *) (a_system_id != NULL) ? a_system_id : "\"\"" ;
00710
00711 *a_external_subset_def = NULL ;
00712
00713 can_resolve_entity = mlview_can_resolve_external_entity (a_app_context,a_external_id,
00714 a_system_id) ;
00715
00716 if (can_resolve_entity)
00717 dialog = GNOME_DIALOG (gnome_dialog_new (_("Dtd choice"),
00718 _("Load that DTD"),
00719 _("Choose another DTD"),
00720 _("Do not validate"),
00721 NULL)) ;
00722 else
00723 dialog = GNOME_DIALOG (gnome_dialog_new (_("Dtd choice"),
00724 _("Choose another DTD"),
00725 _("Do not validate"),
00726 NULL)) ;
00727
00728 gtk_window_set_wmclass (GTK_WINDOW (dialog), "validation-confirmation", "MlView") ;
00729
00730 if ( can_resolve_entity == TRUE)
00731 label_str =
00732 g_strconcat (_("The document refers a DTD with:.\n"),
00733 _("Public ID => "), public_id, "\n",
00734 _("System ID => "), system_id, "\n",
00735 _("Do you want to load and use that DTD or choose another one ?\n"),
00736 NULL) ;
00737 else
00738 label_str =
00739 g_strconcat (_("The document refers a DTD with:.\n"),
00740 _("Public ID => "), public_id, "\n",
00741 _("System ID => "), system_id, "\n",
00742 _("I have not found that DTD. Do you want to choose another one ?\n"),
00743 NULL) ;
00744 label =
00745 gtk_label_new (label_str) ;
00746
00747 if (label_str) {
00748 g_free (label_str) ;
00749 label_str = NULL ;
00750 }
00751 gnome_dialog_close_hides (dialog, FALSE) ;
00752 gnome_dialog_set_close (dialog, FALSE) ;
00753 gtk_box_pack_start (GTK_BOX(dialog->vbox),
00754 label, TRUE, TRUE, 0) ;
00755
00756 gtk_widget_show_all (GTK_WIDGET (dialog->vbox)) ;
00757
00758 gtk_widget_realize (GTK_WIDGET (dialog)) ;
00759 mlview_app_context_set_window_icon (a_app_context, GTK_WIDGET (dialog)) ;
00760 button = gnome_dialog_run (dialog) ;
00761
00762 if (can_resolve_entity == TRUE) {
00763 switch(button){
00764 case 0:
00765
00766 *a_external_subset_def = NULL ;
00767 break ;
00768 case 1:
00769 *a_external_subset_def =
00770 mlview_parsing_utils_let_user_choose_a_dtd (a_app_context, _("Choose a DTD")) ;
00771 result = (*a_external_subset_def == NULL)? FALSE : TRUE ;
00772 break ;
00773 case 2:
00774 result = FALSE ;
00775 break ;
00776 case -1:
00777 default :
00778 break ;
00779 }
00780 } else {
00781 switch(button){
00782 case 0:
00783 *a_external_subset_def =
00784 mlview_parsing_utils_let_user_choose_a_dtd (a_app_context, _("Choose a DTD")) ;
00785 result = (*a_external_subset_def == NULL)? FALSE : TRUE ;
00786 break ;
00787 case 1:
00788 result = FALSE ;
00789 break ;
00790 case -1:
00791 default :
00792 break ;
00793 }
00794 }
00795
00796 if (dialog) {
00797 gnome_dialog_close (dialog) ;
00798 dialog = NULL ;
00799 }
00800
00801 return result ;
00802 }
00803
00804
00817 static void
00818 mlview_parsing_utils_scan_and_build_entities_list (void * a_hash_data,
00819 void * a_output_list,
00820 void * a_entity_name)
00821 {
00822
00823 if (a_entity_name)
00824 *((GList**)a_output_list) =
00825 (void*) g_list_append (*((GList**)a_output_list),
00826 a_entity_name) ;
00827 }
00828
00829
00830 static void
00831 mlview_parsing_utils_scan_and_build_ids_list (void * a_hash_data,
00832 void * a_output_list,
00833 void * a_id_value)
00834 {
00835
00836 if (a_id_value)
00837 *((GList**)a_output_list) =
00838 (void*) g_list_append (*((GList**)a_output_list),
00839 a_id_value) ;
00840 }
00841
00842 static gboolean
00843 is_an_ancestor_node (xmlNode *a_ancestor, xmlNode *a_cur_node)
00844 {
00845 xmlNode * mobile_ptr = a_cur_node ;
00846
00847 g_return_val_if_fail (a_cur_node != NULL, FALSE) ;
00848 g_return_val_if_fail (a_ancestor != NULL, FALSE) ;
00849
00850 while (mobile_ptr) {
00851 if (xmlStrEqual (mobile_ptr->name,
00852 a_ancestor->name))
00853 return TRUE ;
00854 mobile_ptr = mobile_ptr->parent ;
00855 }
00856 return FALSE ;
00857 }
00858
00870 static void
00871 build_required_element_content (MlViewAppContext *a_app_context,
00872 xmlElementContent * a_content,
00873 xmlNode **a_node)
00874 {
00875 xmlElementContent * current_element_content = a_content ;
00876 xmlNode * child_node = NULL , *dummy = NULL;
00877
00878 g_return_if_fail (a_app_context != NULL) ;
00879 g_return_if_fail (MLVIEW_IS_APP_CONTEXT (a_app_context)) ;
00880 g_return_if_fail (a_node != NULL) ;
00881 g_return_if_fail ((*a_node) != NULL) ;
00882
00883 if (!current_element_content)
00884 return ;
00885
00886 dummy = xmlNewNode (NULL, "<!dummy>") ;
00887 switch (current_element_content->type) {
00888
00889 case XML_ELEMENT_CONTENT_OR:
00890
00891
00892
00893
00894 switch (current_element_content->ocur) {
00895 case XML_ELEMENT_CONTENT_ONCE:
00896 case XML_ELEMENT_CONTENT_PLUS:
00897
00898
00899
00900
00901
00902
00903 if (current_element_content->type == XML_ELEMENT_CONTENT_ELEMENT
00904 && current_element_content->name) {
00905
00906 child_node =
00907 xmlNewChild ((*a_node),
00908 NULL,
00909 current_element_content->name,
00910 NULL) ;
00911
00912 mlview_parsing_utils_build_required_children_tree (a_app_context,
00913 &child_node) ;
00914
00915 } else if (current_element_content->c1
00916 && ((current_element_content->c1->ocur == XML_ELEMENT_CONTENT_ONCE)
00917 || current_element_content->c1->ocur == XML_ELEMENT_CONTENT_PLUS)
00918 ) {
00919
00920
00921
00922
00923
00924 if (current_element_content->c1->type == XML_ELEMENT_CONTENT_ELEMENT) {
00925 dummy->name = current_element_content->c1->name ;
00926 if (is_an_ancestor_node (dummy, *a_node) == FALSE) {
00927 build_required_element_content (a_app_context,
00928 current_element_content->c1,
00929 a_node) ;
00930 } else {
00931 build_required_element_content (a_app_context,
00932 current_element_content->c2,
00933 a_node) ;
00934 }
00935 } else {
00936 build_required_element_content (a_app_context,
00937 current_element_content->c1,
00938 a_node) ;
00939 }
00940 } else {
00941
00942
00943
00944
00945 build_required_element_content (a_app_context,
00946 current_element_content->c2,
00947 a_node) ;
00948 }
00949 break ;
00950 default :
00951 break ;
00952 }
00953 break ;
00954
00955 default:
00956 switch (current_element_content->ocur) {
00957 case XML_ELEMENT_CONTENT_ONCE:
00958 case XML_ELEMENT_CONTENT_PLUS:
00959 if (current_element_content->name ) {
00960
00961 child_node =
00962 xmlNewChild ((*a_node),
00963 NULL,
00964 current_element_content->name,
00965 NULL) ;
00966
00967 mlview_parsing_utils_build_required_children_tree (a_app_context,
00968 &child_node) ;
00969 } else {
00970 build_required_element_content (a_app_context,
00971 current_element_content->c1,
00972 a_node) ;
00973
00974 build_required_element_content (a_app_context,
00975 current_element_content->c2,
00976 a_node) ;
00977 }
00978
00979 break ;
00980 default :
00981 break ;
00982
00983 }
00984 break ;
00985 }
00986 if (dummy) {
00987 dummy->name = NULL ;
00988 xmlFreeNode (dummy) ;
00989 dummy = NULL ;
00990 }
00991 }
00992
00993
00994 static gint
00995 g_list_compare_string_elems (gchar *a_str1, gchar *a_str2)
00996 {
00997 g_return_val_if_fail (a_str1 != NULL, -1) ;
00998 g_return_val_if_fail (a_str2 != NULL, 1) ;
00999
01000 return strcmp (a_str1, a_str2) ;
01001 }
01002
01003
01004
01005
01006
01015 xmlDoc *
01016 mlview_parsing_utils_load_xml_file (gchar * a_file_name, MlViewAppContext *a_app_context)
01017 {
01018 xmlDoc *result=NULL ;
01019 xmlParserCtxtPtr parser_context=NULL ;
01020
01021 g_return_val_if_fail(a_file_name != NULL, NULL) ;
01022
01023 if ( strcmp(a_file_name, "")) {
01024 gint load_res ;
01025
01026
01027
01028 load_res = load_xml_document_from_local_file (a_file_name, &parser_context,TRUE, a_app_context) ;
01029
01030 if ( parser_context == NULL ) {
01031 mlview_app_context_error (a_app_context, _("could not load xml document %s"), a_file_name) ;
01032 return NULL;
01033 }
01034 if ( !load_res && parser_context ) {
01035 parser_context->myDoc->name = (xmlChar *) g_strdup(a_file_name);
01036 result = parser_context->myDoc ;
01037 }
01038 }
01039
01040 if (parser_context != NULL) {
01041 xmlFreeParserCtxt (parser_context) ;
01042 }
01043 return result;
01044 }
01045
01046
01056 gint
01057 mlview_parsing_utils_save_xml_doc (xmlDoc * a_xml_doc, gchar * a_file_path,
01058 MlViewAppContext * a_app_context)
01059 {
01060 g_return_val_if_fail (a_xml_doc != NULL, -1) ;
01061 g_return_val_if_fail (a_file_path != NULL, -1) ;
01062
01063 return xmlSaveFormatFile (a_file_path,
01064 a_xml_doc,
01065 1) ;
01066 }
01067
01068
01076 xmlDtd *
01077 mlview_parsing_utils_load_a_dtd (MlViewExternalSubsetDefinition * a_subset_def,
01078 MlViewAppContext * a_app_context)
01079 {
01080 xmlDtd * dtd = NULL ;
01081 xmlSAXHandler * sax_handler = NULL ;
01082
01083 g_return_val_if_fail (a_subset_def != NULL, NULL) ;
01084
01085 if ( a_subset_def->system_id ) {
01086
01087
01088
01089
01090 sax_handler = (xmlSAXHandler*)xmlMalloc (sizeof (xmlSAXHandler)) ;
01091 g_assert (sax_handler != NULL) ;
01092 initxmlDefaultSAXHandler(sax_handler, 0) ;
01093
01094 g_assert (sax_handler != NULL) ;
01095
01096
01097 xmlSetGenericErrorFunc (a_app_context,
01098 (xmlGenericErrorFunc) mlview_app_context_bufferize_error) ;
01099 mlview_app_context_set_error_dialog_title (a_app_context,
01100 _("Some error(s) occured during the parsing of the dtd.\n\n")) ;
01101
01102
01103 sax_handler->resolveEntity = mlview_custom_sax_resolve_entity ;
01104
01105 dtd = custom_xmlSAXParseDTD (a_app_context, sax_handler,
01106 a_subset_def->external_id, a_subset_def->system_id) ;
01107
01108
01109
01110
01111 xmlSetGenericErrorFunc (NULL, NULL) ;
01112
01113 if ( !mlview_app_context_error_buffer_is_empty (a_app_context) )
01114 mlview_app_context_display_buffered_error (a_app_context) ;
01115 else
01116 mlview_app_context_set_error_dialog_title (a_app_context, NULL) ;
01117 }
01118
01119 return dtd ;
01120 }
01121
01122
01130 gint
01131 mlview_parsing_utils_validate_dtd (xmlDoc * a_doc, xmlDtd * a_dtd,
01132 MlViewAppContext * a_app_context)
01133 {
01134 gint result=0 ;
01135 gint validity_status ;
01136 xmlValidCtxt validation_context ;
01137
01138 g_return_val_if_fail (a_doc != NULL, -1) ;
01139
01140 if (a_dtd == NULL)
01141 return 2 ;
01142
01143 validation_context.userData = a_app_context ;
01144 validation_context.error =
01145 (xmlValidityErrorFunc) mlview_app_context_bufferize_error ;
01146 validation_context.warning =
01147 (xmlValidityWarningFunc) mlview_app_context_bufferize_error ;
01148
01149 xmlSetGenericErrorFunc (a_app_context, (xmlGenericErrorFunc)mlview_app_context_bufferize_error) ;
01150 mlview_app_context_set_error_dialog_title (a_app_context, _("Some error(s) occured during the validation of the document.\n\n")) ;
01151 validity_status = xmlValidateDtd (&validation_context, a_doc, a_dtd) ;
01152 xmlSetGenericErrorFunc (a_app_context, (xmlGenericErrorFunc)mlview_app_context_bufferize_error) ;
01153
01154 if (validity_status == 1)
01155
01156 result = 0 ;
01157 else
01158 result = 1 ;
01159 if ( !mlview_app_context_error_buffer_is_empty (a_app_context) )
01160 mlview_app_context_display_buffered_error (a_app_context) ;
01161 else
01162 mlview_app_context_set_error_dialog_title (a_app_context, NULL) ;
01163
01164 return result ;
01165 }
01166
01167
01175 MlViewExternalSubsetDefinition *
01176 mlview_utils_get_a_copy_of_last_external_subset_def (void)
01177 {
01178 MlViewExternalSubsetDefinition * result ;
01179
01180 if (p_external_subset_def == NULL)
01181 return NULL ;
01182 result = mlview_external_subset_definition_clone (p_external_subset_def) ;
01183 mlview_external_subset_definition_destroy (p_external_subset_def) ;
01184 p_external_subset_def = NULL ;
01185
01186 return result ;
01187 }
01188
01189
01190
01191
01192
01193
01194
01195 MlViewExternalSubsetDefinition *
01196 mlview_parsing_utils_let_user_choose_a_dtd (MlViewAppContext * a_app_context,
01197 gchar *a_title)
01198 {
01199 MlViewFileSelection * filesel = NULL ;
01200 MlViewExternalSubsetDefinition *subset_def = NULL ;
01201
01202 enum MLVIEW_SELECTED_BUTTON button_clicked ;
01203 gchar * dtd=NULL ;
01204
01205 g_return_val_if_fail(a_app_context != NULL, NULL) ;
01206
01207 filesel = mlview_app_context_get_file_selector (a_app_context, a_title) ;
01208 g_return_val_if_fail (filesel != NULL, NULL) ;
01209
01210 gtk_widget_realize (GTK_WIDGET (filesel)) ;
01211 mlview_app_context_set_window_icon (a_app_context, GTK_WIDGET (filesel)) ;
01212 button_clicked = mlview_file_selection_run (filesel, TRUE) ;
01213
01214 switch (button_clicked) {
01215 case OK_BUTTON :
01216 dtd = gtk_file_selection_get_filename (GTK_FILE_SELECTION (filesel)) ;
01217 if (dtd)
01218 subset_def = mlview_external_subset_definition_new (NULL, NULL, dtd) ;
01219 break ;
01220 case CANCEL_BUTTON :
01221 case WINDOW_CLOSED :
01222 default :
01223 break ;
01224 }
01225
01226 return subset_def ;
01227 }
01228
01241 gint
01242 mlview_parsing_utils_build_element_name_completion_list (MlViewAppContext *a_app_context,
01243 enum NODE_INSERTION_SCHEME a_insertion_scheme,
01244 xmlNode *a_current_xml_node,
01245 GList ** a_feasible_names_ptr)
01246 {
01247 const xmlChar * feasible_names [MAX_NUMBER_OF_ELEMENT_NAMES_IN_CHOICE_LIST] ;
01248 gint nb_of_names = 0 ;
01249 gchar * validation_is_on = NULL ;
01250
01251 g_return_val_if_fail (a_current_xml_node != NULL, -2) ;
01252 g_return_val_if_fail (a_current_xml_node->type == XML_ELEMENT_NODE, -2) ;
01253 g_return_val_if_fail (feasible_names != NULL, -2) ;
01254
01255 memset (feasible_names, 0, MAX_NUMBER_OF_ELEMENT_NAMES_IN_CHOICE_LIST * sizeof (xmlChar*)) ;
01256
01257 if (a_app_context
01258 && mlview_app_context_settings_exist (a_app_context))
01259 validation_is_on =
01260 mlview_app_context_get_settings_value (a_app_context,
01261 MLVIEW_STG_K_IS_VALIDATION_ON) ;
01262
01263 if ( (validation_is_on == NULL)
01264 || (strcmp (validation_is_on, MLVIEW_STG_V_YES) != 0))
01265 return -1 ;
01266
01267 if ( (a_insertion_scheme == INSERT_BEFORE)
01268 && (a_current_xml_node->type == XML_DOCUMENT_NODE)) {
01269 return 0 ;
01270 }
01271
01272 if ((a_insertion_scheme == INSERT_BEFORE)
01273 && a_current_xml_node->parent
01274 && a_current_xml_node->parent->type == XML_DOCUMENT_NODE) {
01275
01276 return 0 ;
01277 }
01278
01279 if ( (a_insertion_scheme == INSERT_AFTER)
01280 &&(a_current_xml_node->type == XML_DOCUMENT_NODE)){
01281 return 0 ;
01282 }
01283
01284 switch (a_insertion_scheme) {
01285 case INSERT_BEFORE:
01286 nb_of_names =
01287 xmlValidGetValidElements (a_current_xml_node->prev,
01288 a_current_xml_node,
01289 feasible_names,
01290 MAX_NUMBER_OF_ELEMENT_NAMES_IN_CHOICE_LIST) ;
01291 break ;
01292 case INSERT_AFTER:
01293 nb_of_names =
01294 xmlValidGetValidElements (a_current_xml_node,
01295 a_current_xml_node->next,
01296 feasible_names,
01297 MAX_NUMBER_OF_ELEMENT_NAMES_IN_CHOICE_LIST) ;
01298 break ;
01299
01300 case ADD_CHILD :
01301 if (a_current_xml_node->children) {
01302 nb_of_names =
01303 xmlValidGetValidElements (a_current_xml_node->last,
01304 NULL,
01305 feasible_names,
01306 MAX_NUMBER_OF_ELEMENT_NAMES_IN_CHOICE_LIST) ;
01307
01308 } else {
01309 nb_of_names =
01310 xmlValidGetValidElementsChildren (a_current_xml_node,
01311 feasible_names,
01312 MAX_NUMBER_OF_ELEMENT_NAMES_IN_CHOICE_LIST) ;
01313 }
01314
01315 break ;
01316 default :
01317 break ;
01318 }
01319
01320 if (nb_of_names > 0) {
01321 int i ;
01322 GList * list_ptr = NULL ;
01323 GHashTable * names_index =
01324 g_hash_table_new (g_str_hash, g_str_equal) ;
01325
01326 for (list_ptr = *a_feasible_names_ptr ;
01327 list_ptr ;
01328 list_ptr = list_ptr->next) {
01329
01330 if (list_ptr->data)
01331 g_hash_table_insert (names_index,
01332 list_ptr->data,
01333 list_ptr->data) ;
01334 }
01335
01336 for (i=0 ; i < nb_of_names ; i++) {
01337
01338 if ( ((xmlChar**)feasible_names)[i]
01339 && !g_hash_table_lookup (names_index, ((xmlChar**)feasible_names)[i] )) {
01340
01341 (*a_feasible_names_ptr) =
01342 g_list_append (*a_feasible_names_ptr,
01343 ((xmlChar**)feasible_names)[i]) ;
01344 }
01345 }
01346 g_hash_table_destroy (names_index) ;
01347 *a_feasible_names_ptr =
01348 g_list_sort (*a_feasible_names_ptr,
01349 (GCompareFunc) g_list_compare_string_elems) ;
01350 }
01351
01352 return nb_of_names ;
01353 }
01354
01364 gint
01365 mlview_parsing_utils_build_attribute_name_completion_list (MlViewAppContext *a_app_context,
01366 xmlNode * a_current_xml_node,
01367 GList**a_attr_names_compl_list,
01368 gboolean a_required_attributes_only)
01369 {
01370 xmlElement * element_desc = NULL ;
01371 gchar * validation_is_on = NULL ;
01372 gint result = 0 ;
01373
01374 g_return_val_if_fail (a_app_context != NULL, -2) ;
01375 g_return_val_if_fail (MLVIEW_IS_APP_CONTEXT (a_app_context), -2) ;
01376 g_return_val_if_fail (a_current_xml_node != NULL, -2) ;
01377 g_return_val_if_fail (a_attr_names_compl_list != NULL, -2) ;
01378
01379 *a_attr_names_compl_list = NULL ;
01380
01381 if (a_app_context
01382 && mlview_app_context_settings_exist (a_app_context))
01383 validation_is_on =
01384 mlview_app_context_get_settings_value (a_app_context,
01385 MLVIEW_STG_K_IS_VALIDATION_ON) ;
01386
01387 if (validation_is_on == NULL
01388 || (strcmp (validation_is_on, MLVIEW_STG_V_YES) != 0))
01389 return -1 ;
01390
01391 if (a_current_xml_node->doc->intSubset != NULL )
01392 element_desc =
01393 xmlGetDtdElementDesc (a_current_xml_node->doc->intSubset,
01394 a_current_xml_node->name) ;
01395
01396 if ( element_desc == NULL && a_current_xml_node->doc->extSubset )
01397 element_desc =
01398 xmlGetDtdElementDesc (a_current_xml_node->doc->extSubset,
01399 a_current_xml_node->name) ;
01400
01401 if ( element_desc != NULL
01402 && element_desc->attributes != NULL ) {
01403 gboolean add_attribute ;
01404 xmlAttribute * curr_attr = element_desc->attributes ;;
01405
01406 while ( curr_attr ) {
01407 if (a_required_attributes_only == TRUE
01408 && curr_attr->def != XML_ATTRIBUTE_REQUIRED)
01409 add_attribute = FALSE ;
01410 else
01411 add_attribute = TRUE ;
01412
01413 if (add_attribute == TRUE) {
01414 *a_attr_names_compl_list =
01415 g_list_append (*a_attr_names_compl_list,
01416 (gpointer)curr_attr->name) ;
01417 result++ ;
01418 }
01419 curr_attr = curr_attr->nexth ;
01420 }
01421 }
01422
01423 *a_attr_names_compl_list =
01424 g_list_sort (*a_attr_names_compl_list,
01425 (GCompareFunc) g_list_compare_string_elems) ;
01426 return result ;
01427 }
01428
01429
01439 enum MLVIEW_PARSING_UTILS_STATUS
01440 mlview_parsing_utils_get_element_content_table (MlViewAppContext * a_app_context,
01441 xmlElementContent *a_element_content,
01442 GHashTable **a_element_content_table)
01443 {
01444 gchar * validation_is_on = NULL ;
01445 enum MLVIEW_PARSING_UTILS_STATUS result = NOK ;
01446
01447 g_return_val_if_fail (a_app_context != NULL, BAD_PARAMETER) ;
01448 g_return_val_if_fail (MLVIEW_IS_APP_CONTEXT (a_app_context), BAD_PARAMETER) ;
01449
01450 if (a_element_content == NULL)
01451 return OK ;
01452
01453 validation_is_on =
01454 mlview_app_context_get_settings_value (a_app_context,
01455 MLVIEW_STG_K_IS_VALIDATION_ON) ;
01456
01457 if (validation_is_on == NULL
01458 || (strcmp (validation_is_on, MLVIEW_STG_V_YES) != 0))
01459 return -1 ;
01460
01461 if (!*a_element_content_table)
01462 *a_element_content_table = g_hash_table_new (g_str_hash, g_str_equal) ;
01463
01464 g_return_val_if_fail (*a_element_content_table != NULL, GENERIC_ASSERTION_ERROR) ;
01465
01466 switch (a_element_content->type) {
01467 case XML_ELEMENT_CONTENT_PCDATA:
01468 result = OK ;
01469 break ;
01470 case XML_ELEMENT_CONTENT_ELEMENT:
01471 if (a_element_content->name == NULL
01472 || g_hash_table_lookup (*a_element_content_table, a_element_content->name))
01473 break ;
01474
01475 g_hash_table_insert (*a_element_content_table, (gpointer)a_element_content->name, a_element_content) ;
01476
01477 result = OK ;
01478 break ;
01479
01480 case XML_ELEMENT_CONTENT_SEQ:
01481 case XML_ELEMENT_CONTENT_OR:
01482 mlview_parsing_utils_get_element_content_table (a_app_context,
01483 a_element_content->c1,
01484 a_element_content_table) ;
01485
01486 mlview_parsing_utils_get_element_content_table (a_app_context,
01487 a_element_content->c2,
01488 a_element_content_table) ;
01489 result = OK ;
01490 break ;
01491
01492 default:
01493 result = NOK ;
01494 break ;
01495
01496 }
01497
01498 return result ;
01499 }
01500
01501
01511 enum MLVIEW_PARSING_UTILS_STATUS
01512 mlview_parsing_utils_build_required_attributes_list (MlViewAppContext * a_app_context,
01513 xmlNode *a_node)
01514 {
01515 GList *attributes_list = NULL, *list_ptr = NULL ;
01516 gint nb_of_attributes = 0 ;
01517 gchar * validation_is_on = NULL ;
01518
01519 enum MLVIEW_PARSING_UTILS_STATUS result = NOK ;
01520
01521 g_return_val_if_fail (a_app_context != NULL, BAD_PARAMETER) ;
01522 g_return_val_if_fail (MLVIEW_IS_APP_CONTEXT (a_app_context), BAD_PARAMETER) ;
01523 g_return_val_if_fail (a_node != NULL, BAD_PARAMETER) ;
01524
01525 if (mlview_app_context_settings_exist (a_app_context) == FALSE)
01526 return APP_SETTINGS_NOT_AVAILABLE ;
01527
01528 validation_is_on = mlview_app_context_get_settings_value (a_app_context, MLVIEW_STG_K_IS_VALIDATION_ON) ;
01529
01530 if (!validation_is_on
01531 || strcmp (validation_is_on, MLVIEW_STG_V_YES))
01532 return VALIDATION_IS_OFF ;
01533
01534 nb_of_attributes =
01535 mlview_parsing_utils_build_attribute_name_completion_list (a_app_context, a_node,
01536 &attributes_list, TRUE) ;
01537 if (nb_of_attributes < 0)
01538 return NOK ;
01539
01540 else if (nb_of_attributes == 0)
01541 return OK ;
01542
01543 result = OK ;
01544
01545 for (list_ptr = attributes_list ; list_ptr ; list_ptr = list_ptr->next) {
01546 if (!list_ptr->data)
01547 continue ;
01548 else {
01549 GList * attr_value_set = NULL ;
01550 xmlAttribute *attr_desc = NULL ;
01551 gint * last_id_ptr = NULL ;
01552 gchar * default_value = NULL ;
01553 xmlAttr * attr = NULL ;
01554
01555 if (a_node->doc && a_node->doc->intSubset)
01556 attr_desc =
01557 xmlGetDtdAttrDesc (a_node->doc->intSubset,
01558 a_node->name,
01559 (gchar*)list_ptr->data) ;
01560
01561 if (attr_desc == NULL && a_node->doc && a_node->doc->extSubset)
01562 attr_desc =
01563 xmlGetDtdAttrDesc (a_node->doc->extSubset,
01564 a_node->name,
01565 (gchar*)list_ptr->data) ;
01566
01567 if (attr_desc == NULL)
01568 continue ;
01569
01570 attr_desc->doc = a_node->doc ;
01571
01572 last_id_ptr = mlview_app_context_get_last_id_ptr (a_app_context) ;
01573
01574 if (last_id_ptr == NULL)
01575 continue ;
01576
01577 attr_value_set =
01578 mlview_parsing_utils_build_attribute_value_set (a_app_context,
01579 attr_desc, last_id_ptr) ;
01580 if (attr_value_set && attr_value_set->data)
01581 default_value = attr_value_set->data ;
01582 else
01583 default_value = "defaultValue" ;
01584
01585 if (!xmlGetProp (a_node, (gchar*)list_ptr->data))
01586 attr = xmlSetProp (a_node, (gchar*)list_ptr->data,
01587 default_value) ;
01588
01589 if (attr != NULL
01590 &&attr_desc->atype == XML_ATTRIBUTE_ID
01591 && a_node->doc) {
01592 xmlID * id = NULL ;
01593
01594 if (a_node->doc->ids == NULL)
01595 a_node->doc->ids = xmlHashCreate (0) ;
01596
01597 id = xmlMalloc (sizeof (xmlID)) ;
01598 g_assert (id != NULL) ;
01599 id->value = g_strdup (default_value) ;
01600 id->attr = attr ;
01601 xmlHashAddEntry (a_node->doc->ids, (const xmlChar *)default_value, id) ;
01602 }
01603
01604 g_list_free (attr_value_set) ;
01605 attr_value_set = NULL ;
01606 }
01607 }
01608
01609 return result ;
01610 }
01611
01621 enum MLVIEW_PARSING_UTILS_STATUS
01622 mlview_parsing_utils_build_required_children_tree (MlViewAppContext * a_app_context,
01623 xmlNode **a_node)
01624 {
01625 gchar * validation_is_on = NULL ;
01626 xmlElement * element_desc = NULL ;
01627 enum MLVIEW_PARSING_UTILS_STATUS status = NOK ;
01628
01629 g_return_val_if_fail (a_app_context != NULL, BAD_PARAMETER) ;
01630 g_return_val_if_fail (MLVIEW_IS_APP_CONTEXT (a_app_context), BAD_PARAMETER) ;
01631 g_return_val_if_fail (a_node != NULL, BAD_PARAMETER) ;
01632 g_return_val_if_fail (*a_node != NULL, BAD_PARAMETER) ;
01633 g_return_val_if_fail ( ((*a_node)->type == XML_ELEMENT_NODE)
01634 || ((*a_node)->type == XML_ATTRIBUTE_NODE),
01635 BAD_PARAMETER) ;
01636
01637
01638
01639 if (mlview_app_context_settings_exist (a_app_context) == FALSE)
01640 return APP_SETTINGS_NOT_AVAILABLE ;
01641
01642 validation_is_on = mlview_app_context_get_settings_value (a_app_context, MLVIEW_STG_K_IS_VALIDATION_ON) ;
01643
01644 if (!validation_is_on
01645 || strcmp (validation_is_on, MLVIEW_STG_V_YES))
01646 return VALIDATION_IS_OFF ;
01647
01648 g_return_val_if_fail ((*a_node)->doc != NULL, BAD_PARAMETER) ;
01649
01650 g_return_val_if_fail (((*a_node)->doc->intSubset != NULL)
01651 || ((*a_node)->doc->extSubset != NULL) ,
01652 BAD_PARAMETER) ;
01653
01654 g_return_val_if_fail ( ((*a_node)->type == XML_ELEMENT_NODE),
01655 BAD_PARAMETER) ;
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667 element_desc =
01668 xmlGetDtdElementDesc ((*a_node)->doc->intSubset, (*a_node)->name) ;
01669
01670 if (!element_desc)
01671 element_desc =
01672 xmlGetDtdElementDesc ((*a_node)->doc->extSubset,
01673 (*a_node)->name) ;
01674
01675 g_return_val_if_fail (element_desc != NULL,
01676 ELEMENT_DESC_NOT_FOUND) ;
01677
01678 if (!strcmp (element_desc->name, "#PCDATA")) {
01679 xmlNodeSetContent (*a_node, "#PCDATA") ;
01680 return OK ;
01681 }
01682
01683 mlview_parsing_utils_build_required_attributes_list (a_app_context, *a_node) ;
01684
01685
01686
01687 build_required_element_content (a_app_context, element_desc->content, a_node) ;
01688
01689 return status ;
01690 }
01691
01702 GList *
01703 mlview_parsing_utils_build_attribute_value_set (MlViewAppContext *a_app_context,
01704 xmlAttribute * a_attribute_desc,
01705 gint *a_last_id)
01706 {
01707 GList * result = NULL ;
01708 gchar * id_str = NULL ;
01709
01710
01711 g_return_val_if_fail (a_app_context != NULL, NULL) ;
01712 g_return_val_if_fail (MLVIEW_IS_APP_CONTEXT (a_app_context), NULL) ;
01713
01714 g_return_val_if_fail (a_attribute_desc != NULL, NULL) ;
01715 g_return_val_if_fail (a_attribute_desc->name != NULL, NULL) ;
01716 g_return_val_if_fail (a_attribute_desc->doc != NULL, NULL) ;
01717
01718 g_return_val_if_fail (a_last_id != NULL, NULL) ;
01719
01720 switch (a_attribute_desc->atype) {
01721
01722 case XML_ATTRIBUTE_CDATA:
01723 break ;
01724 case XML_ATTRIBUTE_ID:
01725 if (a_attribute_desc->doc->ids == NULL)
01726 a_attribute_desc->doc->ids = xmlHashCreate (0) ;
01727
01728 id_str = g_strdup_printf ("_%d", *a_last_id) ;
01729
01730 while (xmlHashLookup (a_attribute_desc->doc->ids,
01731 id_str)) {
01732
01733 (*a_last_id) ++ ;
01734 id_str = g_strdup_printf ("_%d", *a_last_id) ;
01735
01736 }
01737 result = g_list_append (result,
01738 (gpointer)id_str) ;
01739 break ;
01740 case XML_ATTRIBUTE_IDREF:
01741 case XML_ATTRIBUTE_IDREFS:
01742 if (a_attribute_desc->doc->ids == NULL)
01743 a_attribute_desc->doc->ids = xmlHashCreate (0) ;
01744
01745 xmlHashScan (a_attribute_desc->doc->ids,
01746 (xmlHashScanner) mlview_parsing_utils_scan_and_build_ids_list,
01747 &result) ;
01748 break ;
01749 case XML_ATTRIBUTE_ENTITY:
01750 case XML_ATTRIBUTE_ENTITIES:
01751 if (a_attribute_desc->doc->intSubset) {
01752 xmlHashScan (a_attribute_desc->doc->intSubset->entities,
01753 (xmlHashScanner) mlview_parsing_utils_scan_and_build_entities_list,
01754 &result) ;
01755 }
01756 if (result == NULL
01757 && a_attribute_desc->doc->extSubset) {
01758 xmlHashScan (a_attribute_desc->doc->extSubset->entities,
01759 (xmlHashScanner) mlview_parsing_utils_scan_and_build_entities_list,
01760 &result) ;
01761 }
01762
01763 break ;
01764 case XML_ATTRIBUTE_NMTOKEN:
01765 case XML_ATTRIBUTE_NMTOKENS:
01766 break ;
01767 case XML_ATTRIBUTE_ENUMERATION:
01768 if (a_attribute_desc->tree
01769 && a_attribute_desc->tree->name) {
01770 xmlEnumeration * curr = a_attribute_desc->tree ;
01771 while (curr) {
01772 if ( curr->name)
01773 result = g_list_append (result,
01774 (gpointer) curr->name) ;
01775 curr = curr->next ;
01776 }
01777 }
01778 break ;
01779 case XML_ATTRIBUTE_NOTATION:
01780 break ;
01781 default :
01782 break ;
01783 }
01784 return result ;
01785 }
01786
01787
01798 GList *
01799 mlview_parsing_utils_build_graphical_attribute_value_set (MlViewAppContext *a_app_context,
01800 xmlAttribute * a_attribute_desc,
01801 gint *a_last_id)
01802 {
01803 GList * result = NULL, *value_set ;
01804
01805 g_return_val_if_fail (a_app_context != NULL, NULL) ;
01806 g_return_val_if_fail (MLVIEW_IS_APP_CONTEXT (a_app_context), NULL) ;
01807
01808 g_return_val_if_fail (a_attribute_desc != NULL, NULL) ;
01809 g_return_val_if_fail (a_attribute_desc->name != NULL, NULL) ;
01810 g_return_val_if_fail (a_attribute_desc->doc != NULL, NULL) ;
01811
01812 g_return_val_if_fail (a_last_id != NULL, NULL) ;
01813
01814 value_set =
01815 mlview_parsing_utils_build_attribute_value_set (a_app_context,
01816 a_attribute_desc,
01817 a_last_id) ;
01818 if (value_set) {
01819 GList *list_ptr = NULL ;
01820
01821 for (list_ptr = value_set ;
01822 value_set;
01823 value_set = value_set->next) {
01824
01825 result =
01826 g_list_append (result,
01827 (gpointer)gtk_list_item_new_with_label ((gchar*)list_ptr->data)) ;
01828 }
01829 }
01830
01831 return result ;
01832 }