1 /*  $Id: seq_table_setters.cpp 513580 2016-09-13 11:58:16Z ivanov $
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *               National Center for Biotechnology Information
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government have not placed any restriction on its use or reproduction.
13 *
14 *  Although all reasonable efforts have been taken to ensure the accuracy
15 *  and reliability of the software and data, the NLM and the U.S.
16 *  Government do not and cannot warrant the performance or results that
17 *  may be obtained by using this software or data. The NLM and the U.S.
18 *  Government disclaim all warranties, express or implied, including
19 *  warranties of performance, merchantability or fitness for any particular
20 *  purpose.
21 *
22 *  Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Eugene Vasilchenko
27 *
28 * File Description:
29 *   CSeq_table_Info -- parsed information about Seq-table and its columns
30 *
31 */
32 
33 #include <ncbi_pch.hpp>
34 #include <objmgr/objmgr_exception.hpp>
35 #include <objmgr/impl/seq_table_setters.hpp>
36 #include <serial/iterator.hpp>
37 #include <serial/objectinfo.hpp>
38 #include <objects/general/general__.hpp>
39 #include <objects/seqloc/seqloc__.hpp>
40 #include <objects/seqfeat/seqfeat__.hpp>
41 
42 BEGIN_NCBI_SCOPE
BEGIN_SCOPE(objects)43 BEGIN_SCOPE(objects)
44 
45 
46 /////////////////////////////////////////////////////////////////////////////
47 // CSeq_feat and CSeq_loc setters
48 /////////////////////////////////////////////////////////////////////////////
49 
50 
51 CSeqTableSetFeatField::~CSeqTableSetFeatField()
52 {
53 }
54 
55 
SetInt(CSeq_feat &,int value) const56 void CSeqTableSetFeatField::SetInt(CSeq_feat&, int value) const
57 {
58     NCBI_THROW_FMT(CAnnotException, eOtherError,
59                    "Incompatible Seq-feat field value: "<<value);
60 }
61 
62 
SetInt8(CSeq_feat &,Int8 value) const63 void CSeqTableSetFeatField::SetInt8(CSeq_feat&, Int8 value) const
64 {
65     NCBI_THROW_FMT(CAnnotException, eOtherError,
66                    "Incompatible Seq-feat field value: "<<value);
67 }
68 
69 
SetReal(CSeq_feat &,double value) const70 void CSeqTableSetFeatField::SetReal(CSeq_feat&, double value) const
71 {
72     NCBI_THROW_FMT(CAnnotException, eOtherError,
73                    "Incompatible Seq-feat field value: "<<value);
74 }
75 
76 
SetString(CSeq_feat &,const string & value) const77 void CSeqTableSetFeatField::SetString(CSeq_feat&, const string& value) const
78 {
79     NCBI_THROW_FMT(CAnnotException, eOtherError,
80                    "Incompatible Seq-feat field value: "<<value);
81 }
82 
83 
SetBytes(CSeq_feat &,const vector<char> &) const84 void CSeqTableSetFeatField::SetBytes(CSeq_feat&, const vector<char>& /*value*/) const
85 {
86     NCBI_THROW_FMT(CAnnotException, eOtherError,
87                    "Incompatible Seq-feat field value: vector<char>");
88 }
89 
90 /////////////////////////////////////////////////////////////////////////////
91 
~CSeqTableSetLocField()92 CSeqTableSetLocField::~CSeqTableSetLocField()
93 {
94 }
95 
96 
SetInt(CSeq_loc &,int value) const97 void CSeqTableSetLocField::SetInt(CSeq_loc&, int value) const
98 {
99     NCBI_THROW_FMT(CAnnotException, eOtherError,
100                    "Incompatible Seq-loc field value: "<<value);
101 }
102 
103 
SetInt8(CSeq_loc &,Int8 value) const104 void CSeqTableSetLocField::SetInt8(CSeq_loc&, Int8 value) const
105 {
106     NCBI_THROW_FMT(CAnnotException, eOtherError,
107                    "Incompatible Seq-loc field value: "<<value);
108 }
109 
110 
SetReal(CSeq_loc &,double value) const111 void CSeqTableSetLocField::SetReal(CSeq_loc&, double value) const
112 {
113     NCBI_THROW_FMT(CAnnotException, eOtherError,
114                    "Incompatible Seq-loc field value: "<<value);
115 }
116 
117 
SetString(CSeq_loc &,const string & value) const118 void CSeqTableSetLocField::SetString(CSeq_loc&, const string& value) const
119 {
120     NCBI_THROW_FMT(CAnnotException, eOtherError,
121                    "Incompatible Seq-loc field value: "<<value);
122 }
123 
124 /////////////////////////////////////////////////////////////////////////////
125 
SetString(CSeq_feat & feat,const string & value) const126 void CSeqTableSetComment::SetString(CSeq_feat& feat, const string& value) const
127 {
128     feat.SetComment(value);
129 }
130 
131 
SetString(CSeq_feat & feat,const string & value) const132 void CSeqTableSetDataImpKey::SetString(CSeq_feat& feat, const string& value) const
133 {
134     feat.SetData().SetImp().SetKey(value);
135 }
136 
137 
SetString(CSeq_feat & feat,const string & value) const138 void CSeqTableSetDataRegion::SetString(CSeq_feat& feat, const string& value) const
139 {
140     feat.SetData().SetRegion(value);
141 }
142 
143 
SetInt(CSeq_loc & loc,int value) const144 void CSeqTableSetLocFuzzFromLim::SetInt(CSeq_loc& loc, int value) const
145 {
146     if ( loc.IsPnt() ) {
147         loc.SetPnt().SetFuzz().SetLim(CInt_fuzz_Base::ELim(value));
148     }
149     else if ( loc.IsInt() ) {
150         loc.SetInt().SetFuzz_from().SetLim(CInt_fuzz_Base::ELim(value));
151     }
152     else {
153         NCBI_THROW_FMT(CAnnotException, eOtherError,
154                        "Incompatible fuzz field");
155     }
156 }
157 
158 
SetInt(CSeq_loc & loc,int value) const159 void CSeqTableSetLocFuzzToLim::SetInt(CSeq_loc& loc, int value) const
160 {
161     if ( loc.IsInt() ) {
162         loc.SetInt().SetFuzz_to().SetLim(CInt_fuzz_Base::ELim(value));
163     }
164     else {
165         NCBI_THROW_FMT(CAnnotException, eOtherError,
166                        "Incompatible fuzz field");
167     }
168 }
169 
170 
SetString(CSeq_feat & feat,const string & value) const171 void CSeqTableSetQual::SetString(CSeq_feat& feat, const string& value) const
172 {
173     CRef<CGb_qual> qual(new CGb_qual);
174     qual->SetQual(name);
175     qual->SetVal(value);
176     feat.SetQual().push_back(qual);
177 }
178 
179 
CSeqTableSetExt(const CTempString & fullname)180 CSeqTableSetExt::CSeqTableSetExt(const CTempString& fullname)
181     : name(fullname.substr(2))
182 {
183     if ( name.find('.') != NPOS ) {
184         NStr::Split(name, ".", subfields);
185         name = subfields.back();
186         subfields.pop_back();
187     }
188 }
189 
190 
x_SetField(CSeq_feat & feat) const191 CUser_field& CSeqTableSetExt::x_SetField(CSeq_feat& feat) const
192 {
193     CUser_object::TData* data = &feat.SetExt().SetData();
194     ITERATE ( TSubfields, it, subfields ) {
195         CUser_object::TData* next_data = 0;
196         NON_CONST_ITERATE ( CUser_object::TData, it2, *data ) {
197             const CObject_id& id = (*it2)->GetLabel();
198             CUser_field::TData& data2 = (*it2)->SetData();
199             if ( data2.IsFields() && id.IsStr() && id.GetStr() == *it ) {
200                 next_data = &data2.SetFields();
201                 break;
202             }
203         }
204         if ( !next_data ) {
205             CRef<CUser_field> field(new CUser_field());
206             data->push_back(field);
207             field->SetLabel().SetStr(*it);
208             next_data = &field->SetData().SetFields();
209         }
210         data = next_data;
211     }
212     CRef<CUser_field> field(new CUser_field);
213     field->SetLabel().SetStr(name);
214     data->push_back(field);
215     return *field;
216 }
217 
218 
SetInt(CSeq_feat & feat,int value) const219 void CSeqTableSetExt::SetInt(CSeq_feat& feat, int value) const
220 {
221     x_SetField(feat).SetData().SetInt(value);
222 }
223 
224 
SetInt8(CSeq_feat & feat,Int8 value) const225 void CSeqTableSetExt::SetInt8(CSeq_feat& feat, Int8 value) const
226 {
227     // TODO: Int8 in User-field
228     x_SetField(feat).SetData().SetInt((int)value);
229 }
230 
231 
SetReal(CSeq_feat & feat,double value) const232 void CSeqTableSetExt::SetReal(CSeq_feat& feat, double value) const
233 {
234     x_SetField(feat).SetData().SetReal(value);
235 }
236 
237 
SetString(CSeq_feat & feat,const string & value) const238 void CSeqTableSetExt::SetString(CSeq_feat& feat, const string& value) const
239 {
240     x_SetField(feat).SetData().SetStr(value);
241 }
242 
243 
SetBytes(CSeq_feat & feat,const vector<char> & value) const244 void CSeqTableSetExt::SetBytes(CSeq_feat& feat, const vector<char>& value) const
245 {
246     x_SetField(feat).SetData().SetOs() = value;
247 }
248 
249 
SetInt(CSeq_feat & feat,int value) const250 void CSeqTableSetDbxref::SetInt(CSeq_feat& feat, int value) const
251 {
252     CRef<CDbtag> dbtag(new CDbtag);
253     dbtag->SetDb(name);
254     dbtag->SetTag().SetId(value);
255     feat.SetDbxref().push_back(dbtag);
256 }
257 
258 
SetInt8(CSeq_feat & feat,Int8 value) const259 void CSeqTableSetDbxref::SetInt8(CSeq_feat& feat, Int8 value) const
260 {
261     CRef<CDbtag> dbtag(new CDbtag);
262     dbtag->SetDb(name);
263     dbtag->SetTag().SetId8(value);
264     feat.SetDbxref().push_back(dbtag);
265 }
266 
267 
SetString(CSeq_feat & feat,const string & value) const268 void CSeqTableSetDbxref::SetString(CSeq_feat& feat, const string& value) const
269 {
270     CRef<CDbtag> dbtag(new CDbtag);
271     dbtag->SetDb(name);
272     dbtag->SetTag().SetStr(value);
273     feat.SetDbxref().push_back(dbtag);
274 }
275 
276 
SetInt(CSeq_feat & feat,int value) const277 void CSeqTableSetExtType::SetInt(CSeq_feat& feat, int value) const
278 {
279     feat.SetExt().SetType().SetId(value);
280 }
281 
282 
SetInt8(CSeq_feat & feat,Int8 value) const283 void CSeqTableSetExtType::SetInt8(CSeq_feat& feat, Int8 value) const
284 {
285     feat.SetExt().SetType().SetId8(value);
286 }
287 
288 
SetString(CSeq_feat & feat,const string & value) const289 void CSeqTableSetExtType::SetString(CSeq_feat& feat, const string& value) const
290 {
291     feat.SetExt().SetType().SetStr(value);
292 }
293 
294 
295 /////////////////////////////////////////////////////////////////////////////
296 // CSeqTableSetAnyField
297 /////////////////////////////////////////////////////////////////////////////
298 
299 
300 CObjectInfo
GetNextObject(const CObjectInfo & obj) const301 CSeqTableNextObjectPointer::GetNextObject(const CObjectInfo& obj) const
302 {
303     return obj.SetPointedObject();
304 }
305 
306 
307 CObjectInfo
GetNextObject(const CObjectInfo & obj) const308 CSeqTableNextObjectPtrElementNew::GetNextObject(const CObjectInfo& obj) const
309 {
310     return obj.AddNewPointedElement();
311 }
312 
313 
314 CObjectInfo
GetNextObject(const CObjectInfo & obj) const315 CSeqTableNextObjectElementNew::GetNextObject(const CObjectInfo& obj) const
316 {
317     return obj.AddNewElement();
318 }
319 
320 
321 CObjectInfo
GetNextObject(const CObjectInfo & obj) const322 CSeqTableNextObjectClassMember::GetNextObject(const CObjectInfo& obj) const
323 {
324     return obj.SetClassMember(m_MemberIndex);
325 }
326 
327 
328 CObjectInfo
GetNextObject(const CObjectInfo & obj) const329 CSeqTableNextObjectChoiceVariant::GetNextObject(const CObjectInfo& obj) const
330 {
331     return obj.SetChoiceVariant(m_VariantIndex);
332 }
333 
334 
335 CObjectInfo
GetNextObject(const CObjectInfo & obj) const336 CSeqTableNextObjectUserField::GetNextObject(const CObjectInfo& obj) const
337 {
338     CUser_field& field = *CType<CUser_field>::Get(obj);
339     field.SetLabel().SetStr(m_FieldName);
340     return obj;
341 }
342 
343 
CSeqTableSetAnyObjField(CObjectTypeInfo type,CTempString field)344 CSeqTableSetAnyObjField::CSeqTableSetAnyObjField(CObjectTypeInfo type,
345                                                  CTempString field)
346     : m_SetFinalObject(false)
347 {
348     CConstRef<CSeqTableNextObject> next;
349     for ( ;; ) {
350         switch ( type.GetTypeFamily() ) {
351         default:
352             NCBI_THROW_FMT(CAnnotException, eOtherError,
353                            "Incompatible field: "<<
354                            type.GetTypeInfo()->GetName()<<" "<<field);
355             return;
356         case eTypeFamilyPointer:
357             next.Reset(new CSeqTableNextObjectPointer());
358             type = type.GetPointedType();
359             break;
360         case eTypeFamilyContainer:
361             type = type.GetElementType();
362             if ( type.GetTypeFamily() == eTypeFamilyPointer ) {
363                 next.Reset(new CSeqTableNextObjectPtrElementNew());
364                 type = type.GetPointedType();
365             }
366             else {
367                 next.Reset(new CSeqTableNextObjectElementNew());
368             }
369             break;
370         case eTypeFamilyPrimitive:
371             if ( !field.empty() ) {
372                 NCBI_THROW_FMT(CAnnotException, eOtherError,
373                                "Incompatible field: "<<
374                                type.GetTypeInfo()->GetName()<<"."<<field);
375                 return;
376             }
377             m_SetFinalObject = true;
378             return;
379         case eTypeFamilyClass:
380         case eTypeFamilyChoice:
381             if ( field.empty() ) {
382                 // no fields to set in the class
383                 return;
384             }
385             else {
386                 size_t dot = field.find('.');
387                 CTempString field_name = field;
388                 CTempString next_field;
389                 if ( dot != CTempString::npos ) {
390                     field_name = field.substr(0, dot);
391                     next_field = field.substr(dot+1);
392                 }
393                 field = next_field;
394                 if ( type.GetTypeFamily() == eTypeFamilyClass ) {
395                     TMemberIndex index = type.FindMemberIndex(field_name);
396                     if ( index != kInvalidMember ) {
397                         next = new CSeqTableNextObjectClassMember(index);
398                         type = type.GetClassTypeInfo()->GetMemberInfo(index)
399                             ->GetTypeInfo();
400                     }
401                     else if ( type == CType<CUser_field>() ) {
402                         m_SetUserField = field_name;
403                         return;
404                     }
405                     else {
406                         NCBI_THROW_FMT(CAnnotException, eOtherError,
407                                        "Unknown field: "<<
408                                        type.GetTypeInfo()->GetName()<<"."<<
409                                        field_name);
410                         return;
411                     }
412                 }
413                 else {
414                     TMemberIndex index = type.FindVariantIndex(field_name);
415                     if ( index == kInvalidMember ) {
416                         NCBI_THROW_FMT(CAnnotException, eOtherError,
417                                        "Unknown variant: "<<
418                                        type.GetTypeInfo()->GetName()<<"."<<
419                                        field_name);
420                         return;
421                     }
422                     next.Reset(new CSeqTableNextObjectChoiceVariant(index));
423                     type = type.GetChoiceTypeInfo()->GetVariantInfo(index)
424                         ->GetTypeInfo();
425                 }
426             }
427             break;
428         }
429         m_Nexters.push_back(next);
430     }
431 }
432 
433 
SetObjectField(CObjectInfo obj,int value) const434 void CSeqTableSetAnyObjField::SetObjectField(CObjectInfo obj,
435                                              int value) const
436 {
437     ITERATE ( TNexters, it, m_Nexters ) {
438         obj = (*it)->GetNextObject(obj);
439     }
440     if ( !m_SetUserField.empty() ) {
441         CUser_field* field = CType<CUser_field>::Get(obj);
442         field->SetLabel().SetStr(m_SetUserField);
443         field->SetData().SetInt(value);
444     }
445     else if ( m_SetFinalObject ) {
446         obj.GetPrimitiveTypeInfo()->SetValueInt(obj.GetObjectPtr(), value);
447     }
448 }
449 
450 
SetObjectField(CObjectInfo obj,Int8 value) const451 void CSeqTableSetAnyObjField::SetObjectField(CObjectInfo obj,
452                                              Int8 value) const
453 {
454     ITERATE ( TNexters, it, m_Nexters ) {
455         obj = (*it)->GetNextObject(obj);
456     }
457     if ( !m_SetUserField.empty() ) {
458         CUser_field* field = CType<CUser_field>::Get(obj);
459         field->SetLabel().SetStr(m_SetUserField);
460         // TODO: Int8 in User-field
461         field->SetData().SetInt(int(value));
462     }
463     else if ( m_SetFinalObject ) {
464         obj.GetPrimitiveTypeInfo()->SetValueInt8(obj.GetObjectPtr(), value);
465     }
466 }
467 
468 
SetObjectField(CObjectInfo obj,double value) const469 void CSeqTableSetAnyObjField::SetObjectField(CObjectInfo obj,
470                                              double value) const
471 {
472     ITERATE ( TNexters, it, m_Nexters ) {
473         obj = (*it)->GetNextObject(obj);
474     }
475     if ( !m_SetUserField.empty() ) {
476         CUser_field* field = CType<CUser_field>::Get(obj);
477         field->SetLabel().SetStr(m_SetUserField);
478         field->SetData().SetReal(value);
479     }
480     else {
481         obj.GetPrimitiveTypeInfo()->SetValueDouble(obj.GetObjectPtr(), value);
482     }
483 }
484 
485 
SetObjectField(CObjectInfo obj,const string & value) const486 void CSeqTableSetAnyObjField::SetObjectField(CObjectInfo obj,
487                                              const string& value) const
488 {
489     ITERATE ( TNexters, it, m_Nexters ) {
490         obj = (*it)->GetNextObject(obj);
491     }
492     if ( !m_SetUserField.empty() ) {
493         CUser_field* field = CType<CUser_field>::Get(obj);
494         field->SetLabel().SetStr(m_SetUserField);
495         field->SetData().SetStr(value);
496     }
497     else {
498         obj.GetPrimitiveTypeInfo()->SetValueString(obj.GetObjectPtr(), value);
499     }
500 }
501 
502 
SetObjectField(CObjectInfo obj,const vector<char> & value) const503 void CSeqTableSetAnyObjField::SetObjectField(CObjectInfo obj,
504                                              const vector<char>& value) const
505 {
506     ITERATE ( TNexters, it, m_Nexters ) {
507         obj = (*it)->GetNextObject(obj);
508     }
509     if ( !m_SetUserField.empty() ) {
510         CUser_field* field = CType<CUser_field>::Get(obj);
511         field->SetLabel().SetStr(m_SetUserField);
512         field->SetData().SetOs() = value;
513     }
514     else {
515         obj.GetPrimitiveTypeInfo()->SetValueOctetString(obj.GetObjectPtr(), value);
516     }
517 }
518 
519 
CSeqTableSetAnyLocField(const CTempString & field)520 CSeqTableSetAnyLocField::CSeqTableSetAnyLocField(const CTempString& field)
521     : CSeqTableSetAnyObjField(CSeq_loc::GetTypeInfo(), field)
522 {
523 }
524 
525 
SetInt(CSeq_loc & obj,int value) const526 void CSeqTableSetAnyLocField::SetInt(CSeq_loc& obj, int value) const
527 {
528     SetObjectField(CObjectInfo(&obj, obj.GetTypeInfo()), value);
529 }
530 
531 
SetInt8(CSeq_loc & obj,Int8 value) const532 void CSeqTableSetAnyLocField::SetInt8(CSeq_loc& obj, Int8 value) const
533 {
534     SetObjectField(CObjectInfo(&obj, obj.GetTypeInfo()), value);
535 }
536 
537 
SetReal(CSeq_loc & obj,double value) const538 void CSeqTableSetAnyLocField::SetReal(CSeq_loc& obj, double value) const
539 {
540     SetObjectField(CObjectInfo(&obj, obj.GetTypeInfo()), value);
541 }
542 
543 
SetString(CSeq_loc & obj,const string & value) const544 void CSeqTableSetAnyLocField::SetString(CSeq_loc& obj, const string& value) const
545 {
546     SetObjectField(CObjectInfo(&obj, obj.GetTypeInfo()), value);
547 }
548 
549 
SetBytes(CSeq_loc & obj,const vector<char> & value) const550 void CSeqTableSetAnyLocField::SetBytes(CSeq_loc& obj, const vector<char>& value) const
551 {
552     SetObjectField(CObjectInfo(&obj, obj.GetTypeInfo()), value);
553 }
554 
555 
CSeqTableSetAnyFeatField(const CTempString & field)556 CSeqTableSetAnyFeatField::CSeqTableSetAnyFeatField(const CTempString& field)
557     : CSeqTableSetAnyObjField(CSeq_feat::GetTypeInfo(), field)
558 {
559 }
560 
561 
SetInt(CSeq_feat & obj,int value) const562 void CSeqTableSetAnyFeatField::SetInt(CSeq_feat& obj, int value) const
563 {
564     SetObjectField(CObjectInfo(&obj, obj.GetTypeInfo()), value);
565 }
566 
567 
SetInt8(CSeq_feat & obj,Int8 value) const568 void CSeqTableSetAnyFeatField::SetInt8(CSeq_feat& obj, Int8 value) const
569 {
570     SetObjectField(CObjectInfo(&obj, obj.GetTypeInfo()), value);
571 }
572 
573 
SetReal(CSeq_feat & obj,double value) const574 void CSeqTableSetAnyFeatField::SetReal(CSeq_feat& obj, double value) const
575 {
576     SetObjectField(CObjectInfo(&obj, obj.GetTypeInfo()), value);
577 }
578 
579 
SetString(CSeq_feat & obj,const string & value) const580 void CSeqTableSetAnyFeatField::SetString(CSeq_feat& obj, const string& value) const
581 {
582     SetObjectField(CObjectInfo(&obj, obj.GetTypeInfo()), value);
583 }
584 
585 
SetBytes(CSeq_feat & obj,const vector<char> & value) const586 void CSeqTableSetAnyFeatField::SetBytes(CSeq_feat& obj, const vector<char>& value) const
587 {
588     SetObjectField(CObjectInfo(&obj, obj.GetTypeInfo()), value);
589 }
590 
591 
592 END_SCOPE(objects)
593 END_NCBI_SCOPE
594