1 /*  $Id: dblink_field.cpp 632623 2021-06-03 17:38:11Z 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  * Authors:  Colleen Bollin
27  */
28 
29 
30 #include <ncbi_pch.hpp>
31 
32 #include <objects/general/Dbtag.hpp>
33 #include <objects/general/Object_id.hpp>
34 #include <objmgr/seqdesc_ci.hpp>
35 #include <objmgr/bioseq_ci.hpp>
36 
37 #include <objtools/edit/dblink_field.hpp>
38 #include <objtools/edit/seqid_guesser.hpp>
39 
40 BEGIN_NCBI_SCOPE
41 
42 USING_SCOPE(ncbi::objects);
43 BEGIN_SCOPE(objects)
44 BEGIN_SCOPE(edit)
45 
46 
47 const string kDBLink = "DBLink";
48 
49 
SetVal(CObject & object,const string & newValue,EExistingText existing_text)50 bool CDBLinkField::SetVal(CObject& object, const string & newValue, EExistingText existing_text)
51 {
52     bool rval = false;
53     CSerialObject* serial = dynamic_cast<CSerialObject*>(&object);
54 
55     if (serial)
56     {
57         if (serial->GetThisTypeInfo() == CSeqdesc::GetTypeInfo())
58         {
59             rval = SetVal(static_cast<CSeqdesc&>(*serial), newValue, existing_text);
60         }
61         else
62         if (serial->GetThisTypeInfo() == CUser_object::GetTypeInfo())
63         {
64             rval = SetVal(static_cast<CUser_object&>(*serial), newValue, existing_text);
65         }
66     }
67     return rval;
68 }
69 
SetVal(CSeqdesc & seqdesc,const string & newValue,EExistingText existing_text)70 bool CDBLinkField::SetVal(CSeqdesc& seqdesc, const string & newValue, EExistingText existing_text)
71 {
72     bool rval = false;
73     if (seqdesc.IsUser()) {
74         rval = SetVal(seqdesc.SetUser(), newValue, existing_text);
75     }
76 
77     return rval;
78 }
79 
SetVal(CUser_object & user,const string & newValue,EExistingText existing_text)80 bool CDBLinkField::SetVal(CUser_object& user, const string & newValue, EExistingText existing_text)
81 {
82     bool rval = false;
83     if (IsDBLink(user)) {
84         bool found = false;
85         if (user.IsSetData()) {
86             CUser_object::TData::iterator it = user.SetData().begin();
87             while (it != user.SetData().end()) {
88                 if ((*it)->IsSetLabel() && (*it)->GetLabel().IsStr()) {
89                     EDBLinkFieldType check = GetTypeForLabel((*it)->GetLabel().GetStr());
90                     if (check == m_FieldType) {
91                         rval |= SetVal(**it, newValue, existing_text);
92                         found = true;
93                     }
94                 }
95                 if (!(*it)->IsSetData()) {
96                     it = user.SetData().erase(it);
97                 } else {
98                     it++;
99                 }
100             }
101         }
102         if (!found && (m_ConstraintFieldType != m_FieldType || !m_StringConstraint)) {
103             CRef<CUser_field> new_field(new CUser_field());
104             new_field->SetLabel().SetStr(GetLabelForType(m_FieldType));
105             if (SetVal(*new_field, newValue, eExistingText_replace_old)) {
106                 user.SetData().push_back(new_field);
107                 rval = true;
108             }
109         }
110 
111         // if User object now has no fields, reset so it will be detected as empty
112         if (user.GetData().empty()) {
113             user.ResetData();
114         }
115     }
116     return rval;
117 }
118 
119 
_ParseAndAppend(CUser_field::C_Data::TStrs & strs,const string & newValue,EExistingText existing_text)120 void CDBLinkField::_ParseAndAppend(CUser_field::C_Data::TStrs& strs, const string & newValue, EExistingText existing_text)
121 {
122     vector<CTempStringEx> l;
123     NStr::Split(newValue, ",", l);
124     if (existing_text == eExistingText_replace_old || strs.empty())
125     {
126         strs.clear();
127         for (auto v : l)
128         {
129             strs.push_back(v);
130         }
131     }
132     else
133     {
134         for (auto v : l)
135         {
136             if (existing_text == eExistingText_add_qual)
137             {
138                 strs.push_back(v);
139             }
140             else
141             for (auto s : strs)
142             {
143                 if (m_ConstraintFieldType != m_FieldType || !m_StringConstraint  || m_StringConstraint->DoesTextMatch(s))
144                    AddValueToString(s, v, existing_text);
145             }
146         }
147     }
148 }
149 
SetVal(CUser_field & field,const string & newValue,EExistingText existing_text)150 bool CDBLinkField::SetVal(CUser_field& field, const string & newValue, EExistingText existing_text)
151 {
152     bool rval = false;
153 
154     if (field.IsSetData()) {
155 #if 0
156         if (field.GetData().IsStr()) {
157             string curr_val = field.GetData().GetStr();
158             if (m_ConstraintFieldType != m_FieldType || !m_StringConstraint
159                 || m_StringConstraint->DoesTextMatch(curr_val)) {
160                 CUser_field::C_Data::TStrs& strs = field.SetData().SetStrs();
161                 if (existing_text == eExistingText_add_qual) {
162                     _ParseAndAppend(strs, curr_val);
163                     _ParseAndAppend(strs, newValue);
164                     rval = true;
165                 } else if (AddValueToString(curr_val, newValue, existing_text)) {
166                     field.SetData().SetStrs().push_back(curr_val);
167                     rval = true;
168                 }
169             }
170         } else if (field.GetData().IsStrs()) {
171             if ((existing_text == eExistingText_add_qual || field.GetData().GetStrs().empty())
172                 && (m_ConstraintFieldType != m_FieldType || !m_StringConstraint)) {
173                 field.SetData().SetStrs().push_back(newValue);
174                 rval = true;
175             } else {
176                 NON_CONST_ITERATE(CUser_field::TData::TStrs, s, field.SetData().SetStrs()) {
177                     if (m_ConstraintFieldType != m_FieldType || !m_StringConstraint
178                         || m_StringConstraint->DoesTextMatch(*s)) {
179                         rval |= AddValueToString(*s, newValue, existing_text);
180                     }
181                 }
182             }
183         } else if (field.GetData().Which() == CUser_field::TData::e_not_set) {
184             if (m_ConstraintFieldType != m_FieldType || !m_StringConstraint) {
185                 field.SetData().SetStrs().push_back(newValue);
186                 rval = true;
187             }
188         }
189 #else
190         // first convert older format into newer
191         if (field.GetData().IsStr()) {
192             string curr_val = field.GetData().GetStr();
193             CUser_field::C_Data::TStrs& strs = field.SetData().SetStrs();
194             _ParseAndAppend(strs, curr_val, eExistingText_replace_old);
195         }
196         CUser_field::C_Data::TStrs& strs = field.SetData().SetStrs();
197         _ParseAndAppend(strs, newValue, existing_text);
198         rval = true;
199 #endif
200     } else if (m_ConstraintFieldType != m_FieldType || !m_StringConstraint) {
201         _ParseAndAppend(field.SetData().SetStrs(), newValue, eExistingText_replace_old);
202         rval = true;
203     }
204 
205     if (field.IsSetData() && field.GetData().IsStrs())
206     {
207         field.SetNum(CUser_field::TNum(field.GetData().GetStrs().size()));
208     }
209     return rval;
210 }
211 
212 
GetVal(const CObject & object)213 string CDBLinkField::GetVal( const CObject& object)
214 {
215     vector<string> vals = GetVals(object);
216     if (vals.size() > 0) {
217         return vals[0];
218     } else {
219         return "";
220     }
221 
222 }
223 
224 
GetVals(const CObject & object)225 vector<string> CDBLinkField::GetVals(const CObject& object)
226 {
227     vector<string> vals;
228     const CSeqdesc* seqdesc = dynamic_cast<const CSeqdesc*>(&object);
229     const CUser_object* user = dynamic_cast<const CUser_object*>(&object);
230 
231     if (seqdesc && seqdesc->IsUser()) {
232         user = &(seqdesc->GetUser());
233     }
234     if (IsDBLink(*user) && user->IsSetData()) {
235         CUser_object::TData::const_iterator it = user->GetData().begin();
236         while (it != user->GetData().end()) {
237             if ((*it)->IsSetLabel() && (*it)->GetLabel().IsStr() && (*it)->IsSetData()) {
238                 EDBLinkFieldType check = GetTypeForLabel((*it)->GetLabel().GetStr());
239                 if (check == m_FieldType) {
240                     switch((*it)->GetData().Which()) {
241                         case CUser_field::TData::e_Str:
242                             vals.push_back((*it)->GetData().GetStr());
243                             break;
244                         case CUser_field::TData::e_Strs:
245                             ITERATE(CUser_field::TData::TStrs, s, (*it)->GetData().GetStrs()) {
246                                 vals.push_back(*s);
247                             }
248                             break;
249                         default:
250                             //not handling other types of fields
251                             break;
252                     }
253                 }
254             }
255             ++it;
256         }
257     }
258     return vals;
259 }
260 
261 
GetLabel() const262 string CDBLinkField::GetLabel() const
263 {
264     return "DBLink " + GetLabelForType(m_FieldType);
265 }
266 
267 
SetConstraint(const string & field_name,CConstRef<CStringConstraint> string_constraint)268 void CDBLinkField::SetConstraint(const string& field_name, CConstRef<CStringConstraint> string_constraint)
269 {
270     // constraints only apply for authors, since there could be more than one
271     m_ConstraintFieldType = GetTypeForLabel(field_name);
272     if (m_ConstraintFieldType == eDBLinkFieldType_Unknown || !string_constraint) {
273         string_constraint.Reset(NULL);
274     } else {
275         m_StringConstraint = new CStringConstraint(" ");
276         m_StringConstraint->Assign(*string_constraint);
277     }
278 }
279 
280 
GetTypeForLabel(string label)281 CDBLinkField::EDBLinkFieldType CDBLinkField::GetTypeForLabel(string label)
282 {
283     //CTempString normal = GetNormalizedDBLinkFieldName(label);
284     for (int i = eDBLinkFieldType_Trace; i < eDBLinkFieldType_Unknown; i++) {
285         const string& match = GetLabelForType((EDBLinkFieldType)i);
286         if (NStr::EqualNocase(label, match)) {
287             return (EDBLinkFieldType)i;
288         }
289     }
290     return eDBLinkFieldType_Unknown;
291 }
292 
293 
GetLabelForType(EDBLinkFieldType field_type)294 const string& CDBLinkField::GetLabelForType(EDBLinkFieldType field_type)
295 {
296     static const string g_types[] = {
297         "Trace Assembly Archive",
298         "BioSample",
299         "ProbeDB",
300         "Sequence Read Archive",
301         "BioProject",
302         "Assembly"
303     };
304 
305     if (field_type < 0 || field_type >= eDBLinkFieldType_Unknown)
306         return kEmptyStr;
307     else
308         return g_types[field_type];
309 }
310 
311 
GetObjects(CBioseq_Handle bsh)312 vector<CConstRef<CObject> > CDBLinkField::GetObjects(CBioseq_Handle bsh)
313 {
314     vector<CConstRef<CObject> > objects;
315 
316     CSeqdesc_CI desc_ci(bsh, CSeqdesc::e_User);
317     while (desc_ci) {
318         if (IsDBLink(desc_ci->GetUser())) {
319             CConstRef<CObject> object;
320             object.Reset(&(*desc_ci));
321             objects.push_back(object);
322         }
323         ++desc_ci;
324     }
325 
326     return objects;
327 }
328 
329 
GetApplyObjects(CBioseq_Handle bsh)330 vector<CRef<CApplyObject> > CDBLinkField::GetApplyObjects(CBioseq_Handle bsh)
331 {
332     vector<CRef<CApplyObject> > objects;
333 
334     // add existing descriptors
335     CSeqdesc_CI desc_ci(bsh, CSeqdesc::e_User);
336     while (desc_ci) {
337         if (IsDBLink(desc_ci->GetUser())) {
338             CRef<CApplyObject> obj(new CApplyObject(bsh, *desc_ci));
339             objects.push_back(obj);
340         }
341         ++desc_ci;
342     }
343 
344     if (objects.empty()) {
345         CRef<CApplyObject> new_obj(new CApplyObject(bsh, kDBLink));
346         objects.push_back(new_obj);
347     }
348 
349     return objects;
350 }
351 
352 
GetObjects(CSeq_entry_Handle seh,const string & constraint_field,CRef<CStringConstraint> string_constraint)353 vector<CConstRef<CObject> > CDBLinkField::GetObjects(CSeq_entry_Handle seh, const string& constraint_field, CRef<CStringConstraint> string_constraint)
354 {
355     vector<CConstRef<CObject> > objs;
356     CRef<CScope> scope(&seh.GetScope());
357 
358     CBioseq_CI bi (seh, objects::CSeq_inst::eMol_na);
359     while (bi) {
360         if (NStr::EqualNocase(constraint_field, kFieldTypeSeqId)) {
361             if (CSeqIdGuesser::DoesSeqMatchConstraint(*bi, string_constraint)) {
362                 vector<CConstRef<CObject> > these_objs = GetObjects(*bi);
363                 objs.insert(objs.end(), these_objs.begin(), these_objs.end());
364             }
365         } else {
366             vector<CConstRef<CObject> > these_objs = GetObjects(*bi);
367             ITERATE (vector<CConstRef<CObject> >, it, these_objs) {
368                 if (DoesObjectMatchFieldConstraint (**it, constraint_field, string_constraint, scope)) {
369                     objs.push_back (*it);
370                 }
371             }
372         }
373         ++bi;
374     }
375 
376     return objs;
377 }
378 
379 
IsEmpty(const CObject & object) const380 bool CDBLinkField::IsEmpty(const CObject& object) const
381 {
382     bool rval = false;
383     const CSeqdesc* seqdesc = dynamic_cast<const CSeqdesc*>(&object);
384     const CUser_object* user = dynamic_cast<const CUser_object*>(&object);
385     if (seqdesc && seqdesc->IsUser()) {
386         user = &(seqdesc->GetUser());
387     }
388     if (user && IsDBLink(*user)) {
389         if (!user->IsSetData() || user->GetData().empty()) {
390             rval = true;
391         }
392     }
393 
394     return rval;
395 }
396 
397 
ClearVal(CObject & object)398 void CDBLinkField::ClearVal(CObject& object)
399 {
400     CSeqdesc* seqdesc = dynamic_cast<CSeqdesc*>(&object);
401     CUser_object* user = dynamic_cast<CUser_object*>(&object);
402 
403     if (seqdesc && seqdesc->IsUser()) {
404         user = &(seqdesc->SetUser());
405     }
406     if (user && user->IsSetData()) {
407         CUser_object::TData::iterator it = user->SetData().begin();
408         while (it != user->SetData().end()) {
409             bool do_erase = false;
410             if ((*it)->IsSetLabel() && (*it)->GetLabel().IsStr()) {
411                 EDBLinkFieldType check = GetTypeForLabel((*it)->GetLabel().GetStr());
412                 if (check == m_FieldType) {
413                     do_erase = true;
414                 }
415             }
416             if (do_erase) {
417                 it = user->SetData().erase(it);
418             } else {
419                 it++;
420             }
421         }
422         if (user->GetData().empty()) {
423             user->ResetData();
424         }
425     }
426 }
427 
428 
GetRelatedObjects(const CObject & object,CRef<CScope> scope)429 vector<CConstRef<CObject> > CDBLinkField::GetRelatedObjects(const CObject& object, CRef<CScope> scope)
430 {
431     vector<CConstRef<CObject> > related;
432 
433     const CSeqdesc * obj_desc = dynamic_cast<const CSeqdesc *>(&object);
434     const CSeq_feat * obj_feat = dynamic_cast<const CSeq_feat *>(&object);
435 
436    if (obj_feat) {
437         // find closest related DBLink User Objects
438         CBioseq_Handle bsh = scope->GetBioseqHandle(obj_feat->GetLocation());
439         related = GetObjects(bsh);
440     } else if (obj_desc) {
441         if (obj_desc->IsUser() && IsDBLink(obj_desc->GetUser())) {
442             CConstRef<CObject> obj(obj_desc);
443             related.push_back(obj);
444         } else {
445             CSeq_entry_Handle seh = GetSeqEntryForSeqdesc(scope, *obj_desc);
446             related = GetObjects(seh, GetLabelForType(m_ConstraintFieldType), m_StringConstraint);
447         }
448     }
449 
450     return related;
451 }
452 
453 
GetRelatedObjects(const CApplyObject & object)454 vector<CConstRef<CObject> > CDBLinkField::GetRelatedObjects(const CApplyObject& object)
455 {
456     vector<CConstRef<CObject> > related;
457 
458     const CSeqdesc * obj_desc = dynamic_cast<const CSeqdesc *>(&object);
459     const CSeq_feat * obj_feat = dynamic_cast<const CSeq_feat *>(&object);
460 
461    if (obj_feat) {
462         related = GetObjects(object.GetSEH(), "", CRef<CStringConstraint>(NULL));
463     } else if (obj_desc) {
464         if (obj_desc->IsUser() && IsDBLink(obj_desc->GetUser())) {
465             CConstRef<CObject> obj(obj_desc);
466             related.push_back(obj);
467         } else {
468             related = GetObjects(object.GetSEH(), GetLabelForType(m_ConstraintFieldType), m_StringConstraint);
469         }
470     }
471 
472     return related;
473 }
474 
475 
IsDBLink(const CUser_object & user)476 bool CDBLinkField::IsDBLink (const CUser_object& user)
477 {
478     if (user.GetObjectType() == CUser_object::eObjectType_DBLink) {
479         return true;
480     } else {
481         return false;
482     }
483 }
484 
GetNormalizedDBLinkFieldName(const CTempString & orig_label)485 CTempString CDBLinkField::GetNormalizedDBLinkFieldName(const CTempString& orig_label)
486 {
487     if (NStr::StartsWith(orig_label, "DBLink ")) {
488         return orig_label.substr(7);
489     }
490     else
491         return orig_label;
492 }
493 
494 
495 
GetFieldNames()496 vector<string> CDBLinkField::GetFieldNames()
497 {
498     vector<string> options;
499 
500     for (int field_type = CDBLinkField::eDBLinkFieldType_Trace;
501          field_type < CDBLinkField::eDBLinkFieldType_Unknown;
502          field_type++) {
503         const string& field_name = CDBLinkField::GetLabelForType((CDBLinkField::EDBLinkFieldType)field_type);
504         options.push_back(field_name);
505     }
506 
507     return options;
508 }
509 
510 
MakeUserObject()511 CRef<CUser_object> CDBLinkField::MakeUserObject()
512 {
513     CRef<CUser_object> obj(new CUser_object());
514     obj->SetObjectType(CUser_object::eObjectType_DBLink);
515     return obj;
516 }
517 
518 
CDBLink()519 CDBLink::CDBLink()
520 {
521     m_User = MakeEmptyUserObject();
522 }
523 
524 
CDBLink(CUser_object & user)525 CDBLink::CDBLink(CUser_object& user)
526 {
527     m_User.Reset(new CUser_object());
528     m_User->Assign(user);
529 }
530 
531 
MakeEmptyUserObject()532 CRef<CUser_object> CDBLink::MakeEmptyUserObject()
533 {
534     CRef<CUser_object> obj = CDBLinkField::MakeUserObject();
535     return obj;
536 }
537 
538 
SetBioSample(CUser_object & obj,const string & val,EExistingText existing_text)539 void CDBLink::SetBioSample(CUser_object& obj, const string& val, EExistingText existing_text)
540 {
541     CDBLinkField field(CDBLinkField::eDBLinkFieldType_BioSample);
542     field.SetVal(obj, val, existing_text);
543 }
544 
545 
SetBioProject(CUser_object & obj,const string & val,EExistingText existing_text)546 void CDBLink::SetBioProject(CUser_object& obj, const string& val, EExistingText existing_text)
547 {
548     CDBLinkField field(CDBLinkField::eDBLinkFieldType_BioProject);
549     field.SetVal(obj, val, existing_text);
550 }
551 
552 
SetTrace(CUser_object & obj,const string & val,EExistingText existing_text)553 void CDBLink::SetTrace(CUser_object& obj, const string& val, EExistingText existing_text)
554 {
555     CDBLinkField field(CDBLinkField::eDBLinkFieldType_Trace);
556     field.SetVal(obj, val, existing_text);
557 }
558 
559 
SetProbeDB(CUser_object & obj,const string & val,EExistingText existing_text)560 void CDBLink::SetProbeDB(CUser_object& obj, const string& val, EExistingText existing_text)
561 {
562     CDBLinkField field(CDBLinkField::eDBLinkFieldType_ProbeDB);
563     field.SetVal(obj, val, existing_text);
564 }
565 
566 
SetSRA(CUser_object & obj,const string & val,EExistingText existing_text)567 void CDBLink::SetSRA(CUser_object& obj, const string& val, EExistingText existing_text)
568 {
569     CDBLinkField field(CDBLinkField::eDBLinkFieldType_SRA);
570     field.SetVal(obj, val, existing_text);
571 }
572 
573 
SetAssembly(CUser_object & obj,const string & val,EExistingText existing_text)574 void CDBLink::SetAssembly(CUser_object& obj, const string& val, EExistingText existing_text)
575 {
576     CDBLinkField field(CDBLinkField::eDBLinkFieldType_Assembly);
577     field.SetVal(obj, val, existing_text);
578 }
579 
MergeDBLink(CUser_object & dest,const CUser_object & src)580 void CDBLink::MergeDBLink(CUser_object& dest, const CUser_object& src)
581 {
582     for (const auto& src_field : src.GetData())
583     {
584         if (src_field->IsSetLabel() && src_field->GetLabel().IsStr() && src_field->IsSetData())
585         {
586             CDBLinkField field(CDBLinkField::GetTypeForLabel(src_field->GetLabel().GetStr()));
587 
588             if (src_field->GetData().IsStr())
589             {
590                 field.SetVal(dest, src_field->GetData().GetStr());
591             } else if (src_field->GetData().IsStrs())
592             {
593                 for (const auto& src_value : src_field->GetData().GetStrs())
594                 {
595                     field.SetVal(dest, src_value, eExistingText_add_qual);
596                 }
597             }
598         }
599 
600     }
601 }
602 
SetBioSample(const string & val,EExistingText existing_text)603 CDBLink& CDBLink::SetBioSample(const string& val, EExistingText existing_text)
604 {
605     SetBioSample(*m_User, val, existing_text);
606     return *this;
607 }
608 
609 
SetBioProject(const string & val,EExistingText existing_text)610 CDBLink& CDBLink::SetBioProject(const string& val, EExistingText existing_text)
611 {
612     SetBioProject(*m_User, val, existing_text);
613     return *this;
614 }
615 
616 
SetTrace(const string & val,EExistingText existing_text)617 CDBLink& CDBLink::SetTrace(const string& val, EExistingText existing_text)
618 {
619     SetTrace(*m_User, val, existing_text);
620     return *this;
621 }
622 
623 
SetProbeDB(const string & val,EExistingText existing_text)624 CDBLink& CDBLink::SetProbeDB(const string& val, EExistingText existing_text)
625 {
626     SetProbeDB(*m_User, val, existing_text);
627     return *this;
628 }
629 
630 
SetSRA(const string & val,EExistingText existing_text)631 CDBLink& CDBLink::SetSRA(const string& val, EExistingText existing_text)
632 {
633     SetSRA(*m_User, val, existing_text);
634     return *this;
635 }
636 
637 
SetAssembly(const string & val,EExistingText existing_text)638 CDBLink& CDBLink::SetAssembly(const string& val, EExistingText existing_text)
639 {
640     SetAssembly(*m_User, val, existing_text);
641     return *this;
642 }
643 
644 
GetBioSample(const CUser_object & obj)645 vector<string> CDBLink::GetBioSample(const CUser_object& obj)
646 {
647     CDBLinkField field(CDBLinkField::eDBLinkFieldType_BioSample);
648     return field.GetVals(obj);
649 }
650 
651 
GetBioProject(const CUser_object & obj)652 vector<string> CDBLink::GetBioProject(const CUser_object& obj)
653 {
654     CDBLinkField field(CDBLinkField::eDBLinkFieldType_BioProject);
655     return field.GetVals(obj);
656 }
657 
658 
GetTrace(const CUser_object & obj)659 vector<string> CDBLink::GetTrace(const CUser_object& obj)
660 {
661     CDBLinkField field(CDBLinkField::eDBLinkFieldType_Trace);
662     return field.GetVals(obj);
663 }
664 
665 
GetProbeDB(const CUser_object & obj)666 vector<string> CDBLink::GetProbeDB(const CUser_object& obj)
667 {
668     CDBLinkField field(CDBLinkField::eDBLinkFieldType_ProbeDB);
669     return field.GetVals(obj);
670 }
671 
672 
GetSRA(const CUser_object & obj)673 vector<string> CDBLink::GetSRA(const CUser_object& obj)
674 {
675     CDBLinkField field(CDBLinkField::eDBLinkFieldType_SRA);
676     return field.GetVals(obj);
677 }
678 
679 
GetAssembly(const CUser_object & obj)680 vector<string> CDBLink::GetAssembly(const CUser_object& obj)
681 {
682     CDBLinkField field(CDBLinkField::eDBLinkFieldType_Assembly);
683     return field.GetVals(obj);
684 }
685 
686 
MakeUserObject()687 CRef<CUser_object> CDBLink::MakeUserObject()
688 {
689     CRef<CUser_object> obj(new CUser_object());
690     obj->Assign(*m_User);
691     return obj;
692 }
693 
694 
695 END_SCOPE(edit)
696 END_SCOPE(objects)
697 END_NCBI_SCOPE
698 
699