Salome HOME
Validators return InfoMessage instead of string as an error
[modules/shaper.git] / src / Config / Config_Translator.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        Config_Translator.cpp
4 // Created:     31 May 2016
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "Config_Translator.h"
8 #include "Config_XMLReader.h"
9 #include "Config_Common.h"
10
11 #include <fstream>
12 #include <ostream>
13
14 /**
15  * \class Config_TSReader
16  * \ingroup Config
17  * \brief Class for reading translations from TS files (an XML format).
18  */
19 class Config_TSReader : public Config_XMLReader
20 {
21 public:
22   /// Constructor
23   /// \param theTSFile name of TS file
24   Config_TSReader(const std::string& theTSFile) : Config_XMLReader(theTSFile) {}
25
26   /// Returns content of TS file
27   const Config_Translator::Translator& translator() const { return myTranslator; }
28
29   /// Returns codecs defined in TS files
30   const Config_Translator::Dictionary& codecs() const { return myCodecs; }
31
32 protected:
33   /// Overloaded method. Defines how to process each node
34   virtual void processNode(xmlNodePtr theNode);
35 private:
36   Config_Translator::Translator myTranslator;
37   Config_Translator::Dictionary myCodecs;
38 };
39
40 void Config_TSReader::processNode(xmlNodePtr theNode)
41 {
42   static std::string aName;
43   static std::string aSource;
44   std::string aTranslat;
45
46   if (isNode(theNode, "context", NULL)) {
47     aName = "";
48   } else if (isNode(theNode, "name", NULL)) {
49     aName = getContent(theNode);
50     myCodecs[aName] = encoding();
51   } else if (isNode(theNode, "message", NULL)) {
52     aSource = "";
53   } else if (isNode(theNode, "source", NULL)) {
54     aSource = getContent(theNode);
55   } else if (isNode(theNode, "translation", NULL)) {
56     aTranslat = getContent(theNode);
57     if ((aName.size() > 0) && (aSource.size() > 0))
58       myTranslator[aName][aSource] = aTranslat;
59   }
60 }
61
62 //******************************************************************************
63 //******************************************************************************
64 //******************************************************************************
65 Config_Translator::Translator Config_Translator::myTranslator;
66 Config_Translator::Dictionary Config_Translator::myCodecs;
67
68 #ifdef _DEBUG
69 #ifdef MISSED_TRANSLATION
70 Config_Translator::Translator Config_Translator::myMissed;
71 #endif
72 #endif
73
74 bool Config_Translator::load(const std::string& theFileName)
75 {
76   Config_TSReader aReader(theFileName);
77   aReader.readAll();
78
79   const Translator& aTranslator = aReader.translator();
80   Translator::const_iterator aIt;
81   std::string aContext;
82   Dictionary aDictionary;
83   for (aIt = aTranslator.cbegin(); aIt != aTranslator.cend(); aIt++) {
84     aContext = (*aIt).first;
85     aDictionary = (*aIt).second;
86     if (myTranslator.count(aContext) == 0) {
87       myTranslator[aContext] = aDictionary;
88     } else {
89       Dictionary::const_iterator aDictIt;
90       for (aDictIt = aDictionary.cbegin(); aDictIt != aDictionary.cend(); aDictIt++) {
91         myTranslator[aContext][(*aDictIt).first] = (*aDictIt).second;
92       }
93     }
94   }
95
96   const Dictionary aCodecs = aReader.codecs();
97   Dictionary::const_iterator aDictIt;
98   for (aDictIt = aCodecs.cbegin(); aDictIt != aCodecs.cend(); aDictIt++) {
99     myCodecs[aDictIt->first] = aDictIt->second;
100   }
101   return true;
102 }
103
104 std::string Config_Translator::translate(const Events_InfoMessage& theInfo)
105 {
106   std::string aContext = theInfo.context();
107   std::string aMessage = theInfo.messageString();
108   std::list<std::string> aParameters = theInfo.parameters();
109   return translate(aContext, aMessage, aParameters);
110 }
111
112 std::string insertParameters(const std::string& theString, const std::list<std::string>& theParams)
113 {
114   std::string aResult = theString;
115   std::list<std::string>::const_iterator aIt;
116   int i;
117   char aBuf[20];
118   std::string aParam;
119   for (i=1, aIt = theParams.cbegin(); aIt != theParams.cend(); aIt++, i++) {
120     aParam = (*aIt);
121     sprintf(aBuf, "%d", i);
122     std::string aCode = std::string("%") + std::string(aBuf);
123     size_t aPos = aResult.find(aCode);
124     if (aPos != std::string::npos) {
125       std::string aFirst = aResult.substr(0, aPos);
126       std::string aLast = aResult.substr(aPos + aCode.length(), std::string::npos);
127       aResult = aFirst + aParam + aLast;
128     }
129   }
130   return aResult;
131 }
132
133 std::string Config_Translator::translate(const std::string& theContext,
134                                          const std::string& theMessage, 
135                                          const std::list<std::string>& theParams)
136 {
137   if (myTranslator.count(theContext) > 0) {
138     if (myTranslator[theContext].count(theMessage) > 0) {
139       std::string aTranslation = myTranslator[theContext][theMessage];
140       if (theParams.size() > 0) {
141         aTranslation = insertParameters(aTranslation, theParams);
142       }
143       if (aTranslation.size() > 0)
144         return aTranslation;
145     }
146   }
147   std::string aMsg = theMessage;
148   if (theParams.size() > 0) {
149     aMsg = insertParameters(aMsg, theParams);
150   }
151 #ifdef _DEBUG
152 #ifdef MISSED_TRANSLATION
153   myMissed[theContext][theMessage] = "";
154 #endif
155 #endif
156   return aMsg;
157 }
158
159
160 std::string Config_Translator::codec(const std::string& theContext)
161
162   return (myCodecs.count(theContext) > 0)? myCodecs[theContext] : "UTF-8"; 
163 }
164
165
166 #ifdef _DEBUG
167 #ifdef MISSED_TRANSLATION
168 void Config_Translator::saveMissedTranslations()
169 {
170   if (myMissed.size() == 0)
171     return;
172
173   char* aPath = getenv("ROOT_DIR");
174 #ifdef WIN32
175   std::string aFile = aPath + std::string("\\MissedTranslation.ts");
176 #else
177   std::string aFile = aPath + std::string("/MissedTranslation.ts");
178 #endif
179   std::ofstream oFStream;
180
181   // Delete old file
182   int aa = remove(aFile.c_str());
183
184   oFStream.open(aFile, std::ofstream::out | std::ofstream::app);
185   if (oFStream.is_open()) {
186     Translator::const_iterator aContIt;
187     Dictionary::const_iterator aDictIt;
188     std::string aContext;
189     std::string aSrc;
190     Dictionary aDict;
191
192     oFStream << "<TS version=\"2.0\">" << std::endl;
193     for(aContIt = myMissed.cbegin(); aContIt != myMissed.cend(); aContIt++) {
194       oFStream << "<context>" << std::endl;
195
196       aContext = aContIt->first;
197       oFStream << "  <name>" << aContext << "</name>" << std::endl;
198
199       aDict = aContIt->second;
200       for(aDictIt = aDict.cbegin(); aDictIt != aDict.cend(); aDictIt++) {
201         oFStream << "  <message>" << std::endl;
202         aSrc = aDictIt->first;
203
204         oFStream << "    <source>" << aSrc << "</source>" << std::endl;
205         oFStream << "    <translation>" << "</translation>" << std::endl;
206
207         oFStream << "  </message>" << std::endl;
208       }
209       oFStream << "</context>" << std::endl;
210     }
211
212     oFStream << "</TS>" << std::endl;
213     oFStream.close();
214   }
215 }
216 #endif
217 #endif