1 /*  $Id: gb_block_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 * Author: Colleen Bollin, NCBI
27 *
28 * File Description:
29 *   CGBBlockField class
30 */
31 #include <ncbi_pch.hpp>
32 #include <corelib/ncbistd.hpp>
33 #include <corelib/ncbiobj.hpp>
34 #include <objects/seqfeat/Seq_feat.hpp>
35 #include <objects/seq/Seq_descr.hpp>
36 #include <objects/seqblock/GB_block.hpp>
37 #include <objmgr/seq_entry_ci.hpp>
38 #include <objtools/edit/gb_block_field.hpp>
39 
40 BEGIN_NCBI_SCOPE
BEGIN_SCOPE(objects)41 BEGIN_SCOPE(objects)
42 BEGIN_SCOPE(edit)
43 
44 string CGBBlockField::GetVal(const CObject& object)
45 {
46     vector<string> vals = GetVals(object);
47     if (vals.size() > 0) {
48         return vals[0];
49     } else {
50         return "";
51     }
52 }
53 
54 
GetVals(const CObject & object)55 vector<string> CGBBlockField::GetVals(const CObject& object)
56 {
57     vector<string> rval;
58 
59     const CSeqdesc* desc = dynamic_cast<const CSeqdesc *>(&object);
60     if (desc && desc->IsGenbank()) {
61         switch (m_FieldType) {
62             case eGBBlockFieldType_Keyword:
63                 if (desc->GetGenbank().IsSetKeywords()) {
64                     ITERATE(CGB_block::TKeywords, it, desc->GetGenbank().GetKeywords()) {
65                         rval.push_back(*it);
66                     }
67                 }
68                 break;
69             case eGBBlockFieldType_ExtraAccession:
70                 if (desc->GetGenbank().IsSetExtra_accessions()) {
71                     ITERATE(CGB_block::TKeywords, it, desc->GetGenbank().GetExtra_accessions()) {
72                         rval.push_back(*it);
73                     }
74                 }
75                 break;
76             default:
77                 break;
78         }
79     }
80     return rval;
81 }
82 
83 
IsEmpty(const CObject & object) const84 bool CGBBlockField::IsEmpty(const CObject& object) const
85 {
86     const CSeqdesc* desc = dynamic_cast<const CSeqdesc *>(&object);
87     if (!desc || !desc->IsGenbank()) {
88         return false;
89     }
90     const CGB_block& block = desc->GetGenbank();
91     return block.IsEmpty();
92 }
93 
94 
ClearVal(CObject & object)95 void CGBBlockField::ClearVal(CObject& object)
96 {
97     CSeqdesc* desc = dynamic_cast<CSeqdesc *>(&object);
98     if (!desc || !desc->IsGenbank()) {
99         return;
100     }
101     switch (m_FieldType) {
102         case eGBBlockFieldType_Keyword:
103             desc->SetGenbank().ResetKeywords();
104             break;
105         case eGBBlockFieldType_ExtraAccession:
106             desc->SetGenbank().ResetExtra_accessions();
107             break;
108         default:
109             break;
110     }
111 }
112 
113 
SetVal(CObject & object,const string & val,EExistingText existing_text)114 bool CGBBlockField::SetVal(CObject& object, const string& val, EExistingText existing_text)
115 {
116     bool rval = false;
117 
118     CSeqdesc* desc = dynamic_cast<CSeqdesc *>(&object);
119     if (!desc) {
120         return false;
121     }
122     switch (m_FieldType) {
123         case eGBBlockFieldType_Keyword:
124             if (!desc->IsGenbank()
125                 || !desc->GetGenbank().IsSetKeywords()
126                 || desc->GetGenbank().GetKeywords().empty()
127                 || existing_text == eExistingText_add_qual) {
128                 desc->SetGenbank().SetKeywords().push_back(val);
129                 rval = true;
130             } else {
131                 CGB_block::TKeywords::iterator it = desc->SetGenbank().SetKeywords().begin();
132                 while (it != desc->SetGenbank().SetKeywords().end()) {
133                     string curr_val = *it;
134                     if (!m_StringConstraint || m_StringConstraint->DoesTextMatch(curr_val)) {
135                         if (AddValueToString(curr_val, val, existing_text)) {
136                             *it = curr_val;
137                             rval = true;
138                         }
139                     }
140                     if(NStr::IsBlank(*it)) {
141                         it = desc->SetGenbank().SetKeywords().erase(it);
142                     } else {
143                         ++it;
144                     }
145                 }
146             }
147             break;
148         case eGBBlockFieldType_ExtraAccession:
149             if (!desc->IsGenbank()
150                 || !desc->GetGenbank().IsSetExtra_accessions()
151                 || desc->GetGenbank().GetExtra_accessions().empty()
152                 || existing_text == eExistingText_add_qual) {
153                 desc->SetGenbank().SetExtra_accessions().push_back(val);
154                 rval = true;
155             } else {
156                 CGB_block::TExtra_accessions::iterator it = desc->SetGenbank().SetExtra_accessions().begin();
157                 while (it != desc->SetGenbank().SetExtra_accessions().end()) {
158                     string curr_val = *it;
159                     if (!m_StringConstraint || m_StringConstraint->DoesTextMatch(curr_val)) {
160                         if (AddValueToString(curr_val, val, existing_text)) {
161                             *it = curr_val;
162                             rval = true;
163                         }
164                     }
165                     if(NStr::IsBlank(*it)) {
166                         it = desc->SetGenbank().SetExtra_accessions().erase(it);
167                     } else {
168                         ++it;
169                     }
170                 }
171             }
172             break;
173         default:
174             break;
175     }
176     return rval;
177 }
178 
179 
SetConstraint(const string & field,CConstRef<CStringConstraint> string_constraint)180 void CGBBlockField::SetConstraint(const string& field, CConstRef<CStringConstraint> string_constraint)
181 {
182     EGBBlockFieldType field_type = GetTypeForLabel(field);
183     if (field_type == m_FieldType && string_constraint) {
184         m_StringConstraint = new CStringConstraint(" ");
185         m_StringConstraint->Assign(*string_constraint);
186     } else {
187         m_StringConstraint.Reset(NULL);
188     }
189 }
190 
191 
AllowMultipleValues()192 bool CGBBlockField::AllowMultipleValues()
193 {
194     bool rval = false;
195     switch (m_FieldType) {
196         case eGBBlockFieldType_Keyword:
197         case eGBBlockFieldType_ExtraAccession:
198             rval = true;
199             break;
200         default:
201             break;
202     }
203 
204     return rval;
205 }
206 
207 
GetTypeForLabel(string label)208 CGBBlockField::EGBBlockFieldType CGBBlockField::GetTypeForLabel(string label)
209 {
210     for (int i = eGBBlockFieldType_Keyword; i < eGBBlockFieldType_Unknown; i++) {
211         string match = GetLabelForType((EGBBlockFieldType)i);
212         if (NStr::EqualNocase(label, match)) {
213             return (EGBBlockFieldType)i;
214         }
215     }
216     return eGBBlockFieldType_Unknown;
217 }
218 
219 
GetLabelForType(EGBBlockFieldType field_type)220 string CGBBlockField::GetLabelForType(EGBBlockFieldType field_type)
221 {
222     string rval;
223     switch (field_type) {
224         case eGBBlockFieldType_Keyword:
225             rval = kGenbankBlockKeyword;
226             break;
227         case eGBBlockFieldType_ExtraAccession:
228             rval = "Extra Accession";
229             break;
230         case eGBBlockFieldType_Unknown:
231             break;
232     }
233     return rval;
234 }
235 
236 
237 END_SCOPE(edit)
238 END_SCOPE(objects)
239 END_NCBI_SCOPE
240 
241