From c46069241b7168f45d030ff20b6443da472676c2 Mon Sep 17 00:00:00 2001 From: edgrif <edgrif> Date: Fri, 16 Oct 2009 13:45:33 +0000 Subject: [PATCH] fix feature delete code, needed to access current context, all the align/block etc copying was not correct, also add delete all features code. --- src/zmapView/zmapViewRemoteReceive.c | 360 +++++++++++++++++++-------- 1 file changed, 260 insertions(+), 100 deletions(-) diff --git a/src/zmapView/zmapViewRemoteReceive.c b/src/zmapView/zmapViewRemoteReceive.c index 9ef196d32..041a607fe 100755 --- a/src/zmapView/zmapViewRemoteReceive.c +++ b/src/zmapView/zmapViewRemoteReceive.c @@ -29,9 +29,9 @@ * Exported functions: See zmapView_P.h * * HISTORY: - * Last edited: Sep 11 18:00 2009 (edgrif) + * Last edited: Oct 16 14:44 2009 (edgrif) * Created: Tue Jul 10 21:02:42 2007 (rds) - * CVS info: $Id: zmapViewRemoteReceive.c,v 1.32 2009-09-24 12:50:32 edgrif Exp $ + * CVS info: $Id: zmapViewRemoteReceive.c,v 1.33 2009-10-16 13:45:33 edgrif Exp $ *------------------------------------------------------------------- */ @@ -101,13 +101,22 @@ typedef struct /* some operations are "read only" and hence can use the orig_context, others require edits and * must create an edit_context to do these. */ - ZMapFeatureContext orig_context ; - ZMapFeatureContext edit_context ; + /* Note that only orig_context stays the same throughout processing of a request, other elements + * will change if more than one align/block or whatever is specified in the request. */ + ZMapFeatureContext orig_context ; + ZMapFeatureAlignment orig_align; + ZMapFeatureBlock orig_block; + ZMapFeatureSet orig_feature_set; + ZMapFeature orig_feature; + + + ZMapFeatureContext edit_context ; ZMapFeatureAlignment align; ZMapFeatureBlock block; ZMapFeatureSet feature_set; ZMapFeature feature; + GQuark source_id ; GList *feature_list; @@ -175,6 +184,7 @@ static gboolean xml_request_start_cb(gpointer user_data, ZMapXMLElement zmap_ele static gboolean xml_align_start_cb(gpointer user_data, ZMapXMLElement zmap_element, ZMapXMLParser parser); static gboolean xml_block_start_cb(gpointer user_data, ZMapXMLElement zmap_element, ZMapXMLParser parser); static gboolean xml_featureset_start_cb(gpointer user_data, ZMapXMLElement zmap_element, ZMapXMLParser parser); +static gboolean xml_featureset_end_cb(gpointer user_data, ZMapXMLElement zmap_element, ZMapXMLParser parser); static gboolean xml_feature_start_cb(gpointer user_data, ZMapXMLElement zmap_element, ZMapXMLParser parser); static gboolean xml_export_start_cb(gpointer user_data, ZMapXMLElement zmap_element, ZMapXMLParser parser); static gboolean xml_subfeature_end_cb(gpointer user_data, ZMapXMLElement zmap_element, ZMapXMLParser parser); @@ -183,6 +193,8 @@ static gboolean xml_return_true_cb(gpointer user_data, ZMapXMLElement zmap_eleme static void getFeatureNames(ZMapView view, RequestData input_data, ResponseData output_data) ; static void findUniqueCB(gpointer data, gpointer user_data) ; static void makeUniqueListCB(gpointer key, gpointer value, gpointer user_data) ; +static void copyAddFeature(gpointer key, gpointer value, gpointer user_data) ; + @@ -211,16 +223,17 @@ static ZMapXMLObjTagFunctionsStruct view_starts_G[] = { {NULL, NULL} }; -static ZMapXMLObjTagFunctionsStruct view_ends_G[] = { - { "zmap", xml_return_true_cb }, - { "request", xml_return_true_cb }, - { "align", xml_return_true_cb }, - { "block", xml_return_true_cb }, - { "featureset", xml_return_true_cb }, - { "feature", xml_return_true_cb }, - { "subfeature", xml_subfeature_end_cb }, - {NULL, NULL} -}; +static ZMapXMLObjTagFunctionsStruct view_ends_G[] = + { + { "zmap", xml_return_true_cb }, + { "request", xml_return_true_cb }, + { "align", xml_return_true_cb }, + { "block", xml_return_true_cb }, + { "featureset", xml_featureset_end_cb }, + { "feature", xml_return_true_cb }, + { "subfeature", xml_subfeature_end_cb }, + {NULL, NULL} + } ; /* Must match ZMapViewValidXRemoteActions */ static char *actions_G[ZMAPVIEW_REMOTE_UNKNOWN + 1] = @@ -328,8 +341,10 @@ static char *view_execute_command(char *command_text, gpointer user_data, int *s break ; case ZMAPVIEW_REMOTE_DELETE_FEATURE: - eraseFeatures(view, &input_data, &output_data) ; - break ; + { + eraseFeatures(view, &input_data, &output_data) ; + break ; + } case ZMAPVIEW_REMOTE_CREATE_FEATURE: { @@ -682,7 +697,7 @@ static void delete_failed_make_message(gpointer list_data, gpointer user_data) ZMapFeatureAny feature_any = (ZMapFeatureAny)list_data; ResponseData response_data = (ResponseData)user_data; - if(feature_any->struct_type == ZMAPFEATURE_STRUCT_INVALID) + if (feature_any->struct_type == ZMAPFEATURE_STRUCT_INVALID) { response_data->code = ZMAPXREMOTE_CONFLICT; /* possibly the wrong code */ g_string_append_printf(response_data->messages, @@ -940,7 +955,7 @@ static gboolean xml_align_start_cb(gpointer user_data, ZMapXMLElement set_elemen ZMapXRemoteParseCommandData xml_data = (ZMapXRemoteParseCommandData)user_data; RequestData request_data = (RequestData)(xml_data->user_data); GQuark align_id ; - char *align_name ; + char *align_name = NULL ; if (xml_data->common.action != ZMAPVIEW_REMOTE_INVALID) { @@ -949,27 +964,60 @@ static gboolean xml_align_start_cb(gpointer user_data, ZMapXMLElement set_elemen align_id = zMapXMLAttributeGetValue(attr) ; align_name = (char *)g_quark_to_string(align_id) ; - /* look for align in context. try master and non-master ids */ - if (!(align = zMapFeatureContextGetAlignmentByID(request_data->edit_context, - zMapFeatureAlignmentCreateID(align_name, TRUE))) - && !(align = zMapFeatureContextGetAlignmentByID(request_data->edit_context, - zMapFeatureAlignmentCreateID(align_name, FALSE)))) + if (!(*align_name)) + align_name = NULL ; + } + + if (align_name) + { + gboolean master_align ; + + request_data->orig_align = NULL ; + if ((request_data->orig_align + = zMapFeatureContextGetAlignmentByID(request_data->orig_context, + zMapFeatureAlignmentCreateID(align_name, TRUE)))) + master_align = TRUE ; + else if ((request_data->orig_align + = zMapFeatureContextGetAlignmentByID(request_data->orig_context, + zMapFeatureAlignmentCreateID(align_name, FALSE)))) + master_align = FALSE ; + + if (!(request_data->orig_align)) { - /* not there...create... */ - align = zMapFeatureAlignmentCreate(align_name, FALSE) ; + /* If we can't find the align it's a serious error and we can't carry on. */ + char *err_msg ; + + err_msg = g_strdup_printf("Unknown Align \"%s\": not found in original_context", align_name) ; + zMapXMLParserRaiseParsingError(parser, err_msg) ; + g_free(err_msg) ; + + result = FALSE ; } + else + { + /* look for align in edit context. try master and non-master ids */ + if (!(align = zMapFeatureContextGetAlignmentByID(request_data->edit_context, + zMapFeatureAlignmentCreateID(align_name, + master_align)))) + { + /* not there...create... */ + align = zMapFeatureAlignmentCreate(align_name, FALSE) ; + } - request_data->align = align ; + request_data->align = align ; + result = TRUE ; + } } else { - request_data->align - = (ZMapFeatureAlignment)zMapFeatureAnyCopy((ZMapFeatureAny)(request_data->orig_context->master_align)) ; - } + request_data->orig_align = request_data->orig_context->master_align ; + request_data->align = (ZMapFeatureAlignment)zMapFeatureAnyCopy((ZMapFeatureAny)(request_data->orig_align)) ; - zMapFeatureContextAddAlignment(request_data->edit_context, request_data->align, FALSE) ; + result = TRUE ; + } - result = TRUE ; + if (result) + zMapFeatureContextAddAlignment(request_data->edit_context, request_data->align, FALSE) ; } return result ; @@ -983,46 +1031,81 @@ static gboolean xml_block_start_cb(gpointer user_data, ZMapXMLElement set_elemen ZMapXRemoteParseCommandData xml_data = (ZMapXRemoteParseCommandData)user_data; RequestData request_data = (RequestData)(xml_data->user_data); GQuark block_id ; + char *block_name = NULL ; char *block_seq ; - if(xml_data->common.action != ZMAPVIEW_REMOTE_INVALID) + if (xml_data->common.action != ZMAPVIEW_REMOTE_INVALID) { if ((attr = zMapXMLElementGetAttributeByName(set_element, "name"))) + { + block_id = zMapXMLAttributeGetValue(attr); + block_name = (char *)g_quark_to_string(block_id) ; + + if (!(*block_name)) + block_name = NULL ; + } + + if (block_name) { int ref_start, ref_end, non_start, non_end; ZMapStrand ref_strand, non_strand; - block_id = zMapXMLAttributeGetValue(attr); - - if (zMapFeatureBlockDecodeID(block_id, &ref_start, &ref_end, &ref_strand, - &non_start, &non_end, &non_strand)) + if (!zMapFeatureBlockDecodeID(block_id, &ref_start, &ref_end, &ref_strand, + &non_start, &non_end, &non_strand)) { - if (!(block = zMapFeatureAlignmentGetBlockByID(request_data->align, block_id))) - { - block_seq = (char *)g_quark_to_string(request_data->align->original_id); - block = zMapFeatureBlockCreate(block_seq, - ref_start, ref_end, ref_strand, - non_start, non_end, non_strand); - } + /* Bad format block name. */ + char *err_msg ; + + err_msg = g_strdup_printf("Bad Format Block name: \"%s\"", block_name) ; + zMapXMLParserRaiseParsingError(parser, err_msg) ; + g_free(err_msg) ; + + result = FALSE ; } else { - /* Get the first one! */ - block = zMap_g_hash_table_nth(request_data->align->blocks, 0) ; - } + if (!(request_data->orig_block + = zMapFeatureAlignmentGetBlockByID(request_data->orig_align, block_id))) + { + /* If we can't find the block it's a serious error and we can't carry on. */ + char *err_msg ; - request_data->block = block; + err_msg = g_strdup_printf("Unknown Block \"%s\": not found in original_context", block_name) ; + zMapXMLParserRaiseParsingError(parser, err_msg) ; + g_free(err_msg) ; + + result = FALSE ; + } + else + { + if (!(block = zMapFeatureAlignmentGetBlockByID(request_data->align, block_id))) + { + block_seq = (char *)g_quark_to_string(request_data->align->original_id); + block = zMapFeatureBlockCreate(block_seq, + ref_start, ref_end, ref_strand, + non_start, non_end, non_strand); + } + else + { + /* Get the first one! */ + block = zMap_g_hash_table_nth(request_data->align->blocks, 0) ; + } + + request_data->block = block; + result = TRUE ; + } + } } else { /* Get the first one! */ - request_data->block - = (ZMapFeatureBlock)zMapFeatureAnyCopy(zMap_g_hash_table_nth(request_data->orig_context->master_align->blocks, 0)) ; + request_data->orig_block = zMap_g_hash_table_nth(request_data->orig_context->master_align->blocks, 0) ; + request_data->block = (ZMapFeatureBlock)zMapFeatureAnyCopy((ZMapFeatureAny)(request_data->orig_block)) ; + result = TRUE ; } - zMapFeatureAlignmentAddBlock(request_data->align, request_data->block); - - result = TRUE ; + if (result) + zMapFeatureAlignmentAddBlock(request_data->align, request_data->block); } return result ; @@ -1041,6 +1124,8 @@ static gboolean xml_featureset_start_cb(gpointer user_data, ZMapXMLElement set_e if (xml_data->common.action != ZMAPVIEW_REMOTE_INVALID) { + request_data->source_id = 0 ; /* reset needed for remove features. */ + if ((attr = zMapXMLElementGetAttributeByName(set_element, "name"))) { ZMapGFFSet set_data ; @@ -1054,6 +1139,7 @@ static gboolean xml_featureset_start_cb(gpointer user_data, ZMapXMLElement set_e set_id = zMapFeatureSetCreateID(set_name); request_data->source_id = set_id ; + /* Check to see if we can find this source name in any of the featuresets. */ if (!(set_data = g_hash_table_lookup(request_data->view->source_2_featureset, GINT_TO_POINTER(set_id)))) { @@ -1074,6 +1160,10 @@ static gboolean xml_featureset_start_cb(gpointer user_data, ZMapXMLElement set_e /* Check we can find the _featureset_ id..... */ + +#ifdef ED_G_NEVER_INCLUDE_THIS_CODE + /* This is surely the wrong test..... */ + if (result && g_hash_table_lookup(request_data->view->featureset_2_stylelist, GUINT_TO_POINTER(featureset_id)) == NULL) { @@ -1087,82 +1177,124 @@ static gboolean xml_featureset_start_cb(gpointer user_data, ZMapXMLElement set_e result = FALSE ; } +#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */ if (result) { - /* Make sure this feature set is a child of the block........ */ - if (!(feature_set = zMapFeatureBlockGetSetByID(request_data->block, featureset_id))) + if (!(request_data->orig_feature_set + = zMapFeatureBlockGetSetByID(request_data->orig_block, featureset_id))) { - feature_set = zMapFeatureSetCreate(featureset_name, NULL); - zMapFeatureBlockAddFeatureSet(request_data->block, feature_set); - } + /* If we can't find the featureset it's a serious error and we can't carry on. */ + char *err_msg ; + err_msg = g_strdup_printf("Unknown FeatureSet \"%s\": not found in original_block", + featureset_name) ; + zMapXMLParserRaiseParsingError(parser, err_msg) ; + g_free(err_msg) ; + + result = FALSE ; + } + else + { + /* Make sure this feature set is a child of the block........ */ + if (!(feature_set = zMapFeatureBlockGetSetByID(request_data->block, featureset_id))) + { + feature_set = zMapFeatureSetCreate(featureset_name, NULL); + zMapFeatureBlockAddFeatureSet(request_data->block, feature_set); + } - request_data->feature_set = feature_set; + request_data->feature_set = feature_set; - request_data->edit_context->feature_set_names - = g_list_append(request_data->edit_context->feature_set_names, GINT_TO_POINTER(featureset_id)) ; + request_data->edit_context->feature_set_names + = g_list_append(request_data->edit_context->feature_set_names, GINT_TO_POINTER(featureset_id)) ; + } } - } - else - { - /* Get the first one! No one in their right mind should leave this to chance.... */ - request_data->feature_set = zMap_g_hash_table_nth(request_data->block->feature_sets, 0) ; + else + { + /* Get the first one! No one in their right mind should leave this to chance.... */ + request_data->orig_feature_set = zMap_g_hash_table_nth(request_data->orig_block->feature_sets, 0) ; + request_data->feature_set + = (ZMapFeatureSet)zMapFeatureAnyCopy((ZMapFeatureAny)(request_data->orig_feature_set)) ; - result = TRUE ; + result = TRUE ; + } } - - switch (xml_data->common.action) + if (result) { - case ZMAPVIEW_REMOTE_LOAD_FEATURES: - { - request_data->feature_sets = g_list_append(request_data->feature_sets, GINT_TO_POINTER(set_id)) ; - - break; - } - - case ZMAPVIEW_REMOTE_GET_FEATURE_NAMES: - { - if (result && (attr = zMapXMLElementGetAttributeByName(set_element, "start"))) + switch (xml_data->common.action) + { + case ZMAPVIEW_REMOTE_LOAD_FEATURES: { - request_data->start = strtol((char *)g_quark_to_string(zMapXMLAttributeGetValue(attr)), - (char **)NULL, 10); + request_data->feature_sets = g_list_append(request_data->feature_sets, GINT_TO_POINTER(set_id)) ; + + break; } - else + + case ZMAPVIEW_REMOTE_GET_FEATURE_NAMES: { - zMapXMLParserRaiseParsingError(parser, "start is a required attribute for feature."); - result = FALSE ; - } + if (result && (attr = zMapXMLElementGetAttributeByName(set_element, "start"))) + { + request_data->start = strtol((char *)g_quark_to_string(zMapXMLAttributeGetValue(attr)), + (char **)NULL, 10); + } + else + { + zMapXMLParserRaiseParsingError(parser, "start is a required attribute for feature."); + result = FALSE ; + } - if (result && (attr = zMapXMLElementGetAttributeByName(set_element, "end"))) - { - request_data->end = strtol((char *)g_quark_to_string(zMapXMLAttributeGetValue(attr)), - (char **)NULL, 10); - } - else - { - zMapXMLParserRaiseParsingError(parser, "end is a required attribute for feature."); - result = FALSE ; - } - - break; - } - + if (result && (attr = zMapXMLElementGetAttributeByName(set_element, "end"))) + { + request_data->end = strtol((char *)g_quark_to_string(zMapXMLAttributeGetValue(attr)), + (char **)NULL, 10); + } + else + { + zMapXMLParserRaiseParsingError(parser, "end is a required attribute for feature."); + result = FALSE ; + } + break; + } - default: - break ; + default: + break ; + } } + } + return result ; +} +static gboolean xml_featureset_end_cb(gpointer user_data, ZMapXMLElement set_element, + ZMapXMLParser parser) +{ + gboolean result = FALSE ; + ZMapXRemoteParseCommandData xml_data = (ZMapXRemoteParseCommandData)user_data; + RequestData request_data = (RequestData)(xml_data->user_data); + if (xml_data->common.action != ZMAPVIEW_REMOTE_INVALID) + { + /* Only do stuff if a feature set was found and has features. */ + if (request_data->feature_set && request_data->feature_set->features) + { + /* If deleting and no feature was specified then delete them all. NOTE that if + * a source name was given then only features from _that_ source are deleted, not + * all features in the column. */ + if (xml_data->common.action == ZMAPVIEW_REMOTE_DELETE_FEATURE && !(request_data->feature_list)) + { + g_hash_table_foreach(request_data->orig_feature_set->features, + copyAddFeature, request_data) ; + } + } } return result ; } + static gboolean xml_feature_start_cb(gpointer user_data, ZMapXMLElement feature_element, ZMapXMLParser parser) { @@ -1789,3 +1921,31 @@ static void makeUniqueListCB(gpointer key, gpointer value, gpointer user_data) } + +/* A GHFunc() to copy a feature and add it to the supplied list. */ +static void copyAddFeature(gpointer key, gpointer value, gpointer user_data) +{ + ZMapFeature feature = (ZMapFeature)value ; + RequestData request_data = (RequestData)user_data ; + ZMapFeatureAny feature_any ; + + /* Only add to this list if there is no source name or the feature and source + * names match, caller will have given a source name. */ + if (!(request_data->source_id) || feature->source_id == request_data->source_id) + { + /* THIS DOESN'T DO A DEEP ENOUGH COPY, WE FAIL LATER FOR SOME ACTIONS + * BECAUSE STUFF LIKE THE HOMOL DATA IS NOT COPIED SO WE CAN'T FIND + * THE FEATURE IN THE HASH. */ + if ((feature_any = zMapFeatureAnyCopy((ZMapFeatureAny)feature))) + { + ZMapFeatureAny feature_copy ; + + zMapFeatureSetAddFeature(request_data->feature_set, (ZMapFeature)feature_any) ; + + feature_copy = zMapFeatureAnyCopy(feature_any) ; + request_data->feature_list = g_list_append(request_data->feature_list, feature_copy) ; + } + } + + return ; +} -- GitLab