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