NCBI C++ ToolKit
convert_comment.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

00001 /*  $Id: convert_comment.cpp 29154 2013-11-01 15:17:27Z filippov $
00002  * ===========================================================================
00003  *
00004  *                            PUBLIC DOMAIN NOTICE
00005  *               National Center for Biotechnology Information
00006  *
00007  *  This software/database is a "United States Government Work" under the
00008  *  terms of the United States Copyright Act.  It was written as part of
00009  *  the author's official duties as a United States Government employee and
00010  *  thus cannot be copyrighted.  This software/database is freely available
00011  *  to the public for use. The National Library of Medicine and the U.S.
00012  *  Government have not placed any restriction on its use or reproduction.
00013  *
00014  *  Although all reasonable efforts have been taken to ensure the accuracy
00015  *  and reliability of the software and data,  the NLM and the U.S.
00016  *  Government do not and cannot warrant the performance or results that
00017  *  may be obtained by using this software or data. The NLM and the U.S.
00018  *  Government disclaim all warranties,  express or implied,  including
00019  *  warranties of performance,  merchantability or fitness for any particular
00020  *  purpose.
00021  *
00022  *  Please cite the author in any work or product based on this material.
00023  *
00024  * ===========================================================================
00025  *
00026  * Authors:  Igor Filippov
00027  */
00028 
00029 #include <ncbi_pch.hpp>
00030 #include <objmgr/scope.hpp>
00031 #include <gui/objutils/cmd_del_desc.hpp>
00032 #include <gui/objutils/cmd_create_desc.hpp>
00033 #include <gui/objutils/descriptor_change.hpp>
00034 #include <gui/packages/pkg_sequence_edit/convert_comment.hpp>
00035 
00036 BEGIN_NCBI_SCOPE
00037 using namespace objects;
00038 
00039 
00040 static void s_split(const string &s, string delim, vector<string> &elems) 
00041 {
00042     unsigned int start = 0;
00043     while (start < s.length())
00044     {
00045         unsigned int finish = s.find(delim,start);
00046         if (finish == string::npos) finish = s.length();
00047         string item = s.substr(start,finish-start);
00048         NStr::TruncateSpacesInPlace (item);
00049         if (!item.empty()) elems.push_back(item);
00050         start = finish+delim.length();
00051     }
00052 }
00053 
00054 string CConvertComment::ApplyToComment (string comment, CCmdComposite* composite,CSeq_entry_Handle seh)
00055 {
00056     string result = comment;
00057     
00058     if (comment.find("-START##") != string::npos && comment.find("-END##") != string::npos && comment.find(m_DelimiterNameValue) != string::npos)
00059     {
00060         string prefix,suffix;
00061         unsigned int e = comment.find("-START##");
00062         unsigned int b = comment.rfind("##",e);
00063         if (b == string::npos) b = 0;
00064         e += strlen("-START##");
00065         prefix = comment.substr(b,e-b);
00066         comment.erase(0,e);
00067 
00068         e = comment.find("-END##");
00069         b = comment.rfind("##",e);
00070         if (b == string::npos) b = 0;
00071         e += strlen("-END##");
00072         suffix = comment.substr(b,e-b);
00073         comment.erase(b,string::npos);
00074 
00075         vector<string> lines;
00076         string name;
00077         vector< pair<string,string> > fields;
00078         s_split(comment,m_DelimiterFields,lines);  
00079         for (unsigned int i=0; i<lines.size(); ++i)
00080         {
00081             NStr::ReplaceInPlace (lines[i], "\r", "");
00082             vector<string> field;
00083             s_split(lines[i],m_DelimiterNameValue,field);
00084             if (field.size() == 2)
00085                 fields.push_back(pair<string,string>(field[0],field[1]));
00086             else if (field.size() == 1)                                       
00087             {
00088                 if (!name.empty())
00089                 {
00090                     fields.push_back(pair<string,string>(name,field[0]));
00091                     name.clear();
00092                 }
00093                 else
00094                     name = field[0];
00095             }
00096         }
00097 
00098         if (!fields.empty())
00099         {
00100             CRef<CSeqdesc> descr(new CSeqdesc());
00101             descr->Select(CSeqdesc::e_User);
00102             CUser_object& user = descr->SetUser();
00103             user.SetType().SetStr("StructuredComment");
00104             if (!prefix.empty())
00105                 user.AddField("StructuredCommentPrefix",prefix);
00106             for (unsigned int i=0; i<fields.size(); ++i)
00107                 user.AddField(fields[i].first,fields[i].second);
00108             if (!suffix.empty())
00109                 user.AddField("StructuredCommentSuffix",suffix);
00110             
00111             CIRef<IEditCommand> cmdAddDesc(new CCmdCreateDesc(seh, *descr));
00112             composite->AddCommand(*cmdAddDesc);
00113 
00114             e = result.find("-START##");
00115             b = result.rfind("##",e);
00116             if (b == string::npos) b = 0;
00117             e = result.find("-END##");
00118             e += strlen("-END##");
00119             result.erase(b,e-b);
00120         }
00121     }
00122         return result;
00123 }
00124 
00125 void CConvertComment::ApplyToCSeq_entry (objects::CSeq_entry_Handle tse, const CSeq_entry& se, CCmdComposite* composite)  
00126 {
00127 
00128     FOR_EACH_SEQDESC_ON_SEQENTRY (it, se) 
00129     {
00130         if ((*it)->IsComment()) 
00131         {
00132             CSeq_entry_Handle seh = tse.GetScope().GetSeq_entryHandle(se);
00133             string modified = ApplyToComment((*it)->GetComment(),composite,seh);
00134             if (modified != (*it)->GetComment())
00135             {
00136                 if (modified.empty())
00137                 {
00138                     CIRef<IEditCommand> cmdDelDesc(new CCmdDelDesc(seh, **it));
00139                     composite->AddCommand(*cmdDelDesc);
00140                 }
00141                 else
00142                 {
00143                     CRef<CSerialObject> edited_object;
00144                     edited_object.Reset((CSerialObject*)CSeqdesc::GetTypeInfo()->Create());
00145                     edited_object->Assign(**it);
00146                     CSeqdesc& edited_seqdesc = dynamic_cast<CSeqdesc&>(*edited_object);
00147                     edited_seqdesc.SetComment(modified);
00148                     CChangeSeqDescCommand* cmd = new CChangeSeqDescCommand();
00149                     CObject* actual = (CObject*) &(**it);
00150                     cmd->Add(actual, CConstRef<CObject>(edited_object));
00151                     composite->AddCommand(*cmd);
00152                 }
00153             }
00154         }
00155     }
00156 
00157     if (se.IsSet()) 
00158     {
00159         FOR_EACH_SEQENTRY_ON_SEQSET (it, se.GetSet()) 
00160         {
00161             ApplyToCSeq_entry (tse, **it, composite);
00162         }
00163     }
00164 }
00165 
00166 
00167 bool CConvertComment::apply(objects::CSeq_entry_Handle tse, ICommandProccessor* cmdProcessor, string title, string delim_name_value, string delim_fields)
00168 {
00169     if (tse) 
00170     {
00171         m_DelimiterNameValue = delim_name_value;
00172         m_DelimiterFields = delim_fields;
00173         CRef<CCmdComposite> composite(new CCmdComposite(title)); 
00174         ApplyToCSeq_entry (tse, *(tse.GetCompleteSeq_entry()), composite);   
00175         cmdProcessor->Execute(composite.GetPointer());
00176         return true;
00177     }
00178     else
00179         return false;
00180 }
00181 
00182 
00183 
00184 
00185 END_NCBI_SCOPE
Modified on Mon Sep 22 17:20:38 2014 by modify_doxy.py rev. 426318