Isis 3 Programmer Reference
PvlTranslationTable.cpp
Go to the documentation of this file.
1 
23 #include <fstream>
24 #include <sstream>
25 
26 #include <QDebug>
27 
28 #include "IException.h"
29 #include "IString.h"
30 #include "Message.h"
31 #include "Pvl.h"
32 #include "PvlTranslationTable.h"
33 
34 using namespace std;
35 namespace Isis {
36 
42  PvlTranslationTable::PvlTranslationTable(FileName transFile) {
43  AddTable(transFile.expanded());
44  }
45 
46 
52  PvlTranslationTable::PvlTranslationTable(std::istream &istr) {
53  istr >> p_trnsTbl;
54  }
55 
56 
60  PvlTranslationTable::PvlTranslationTable() {
61  }
62 
63 
67  PvlTranslationTable::~PvlTranslationTable() {
68  }
69 
70 
78  Pvl &PvlTranslationTable::TranslationTable() {
79  return p_trnsTbl;
80  }
81 
82 
90  const Pvl &PvlTranslationTable::TranslationTable() const {
91  return p_trnsTbl;
92  }
93 
94 
100  void PvlTranslationTable::AddTable(const QString &transFile) {
101  p_trnsTbl.read(FileName(transFile).expanded());
102  }
103 
104 
118  void PvlTranslationTable::AddTable(std::istream &transStm) {
119  transStm >> p_trnsTbl;
120 
121  // pair< name, size > of acceptable keywords.
122  // A size of -1 means non-zero size.
123  vector< pair<QString, int> > validKeywordSizes = validKeywords();
124 
125  for (int i = 0; i < p_trnsTbl.groups(); i++) {
126  PvlGroup currGroup = p_trnsTbl.group(i);
127 
128  if (!currGroup.hasKeyword("InputKey")) {
129  QString message = "Unable to find InputKey for group ["
130  + currGroup.name() + "] in file [" +
131  p_trnsTbl.fileName() + "]";
132  throw IException(IException::User, message, _FILEINFO_);
133  }
134 
135  for (int j = 0; j < currGroup.keywords(); j++) {
136  bool validKeyword = false;
137  bool keywordSizeMismatch = false;
138 
139  const PvlKeyword &currKey = currGroup[j];
140 
141  // Test this keyword for validity
142  for (int key = 0;
143  !validKeyword && key < (int)validKeywordSizes.size();
144  key++) {
145 
146  // If this is the right keyword (names match) then test sizes
147  if (currKey.name() == validKeywordSizes[key].first) {
148 
149  // if -1 then test that size() > 0
150  if (validKeywordSizes[key].second == -1) {
151  if (currKey.size() > 0) {
152  validKeyword = true;
153  }
154  }
155  // otherwise should exact match
156  else if (currKey.size() == validKeywordSizes[key].second) {
157  validKeyword = true;
158  }
159  else {
160  keywordSizeMismatch = true;
161  }
162  }
163 
164  }
165 
166  // if we had an error report it
167  if (!validKeyword) {
168  if (!keywordSizeMismatch) {
169  QString message = "Keyword [" + currKey.name();
170  message += "] is not a valid keyword.";
171  message += " Error in file [" + p_trnsTbl.fileName() + "]" ;
172 
173  throw IException(IException::User, message, _FILEINFO_);
174  }
175  else {
176  QString message = "Keyword [" + currKey.name();
177  message += "] does not have the correct number of elements.";
178  message += " Error in file [" + p_trnsTbl.fileName() + "]" ;
179 
180  throw IException(IException::User, message, _FILEINFO_);
181  }
182 
183  }
184  }
185  }
186  }
187 
188 
195  vector< pair<QString, int> > PvlTranslationTable::validKeywords() const {
196 
197  vector< pair<QString, int> > validKeywords;
198  validKeywords.push_back(pair<QString, int>("Translation", 2));
199  validKeywords.push_back(pair<QString, int>("OutputName", 1));
200  validKeywords.push_back(pair<QString, int>("InputGroup", -1));
201  validKeywords.push_back(pair<QString, int>("InputPosition", -1));
202  validKeywords.push_back(pair<QString, int>("OutputPosition", -1));
203  validKeywords.push_back(pair<QString, int>("Auto", 0));
204  validKeywords.push_back(pair<QString, int>("Optional", 0));
205  validKeywords.push_back(pair<QString, int>("InputKey", 1));
206  validKeywords.push_back(pair<QString, int>("InputDefault", -1));
207  validKeywords.push_back(pair<QString, int>("InputKeyDependencies", -1));
208 
209  return validKeywords;
210  }
211 
212 
232  QString PvlTranslationTable::Translate(const QString translationGroupName,
233  const QString inputKeyValue) const {
234 
235  const PvlGroup &translationGroup = findTranslationGroup(translationGroupName);
236 
237  // If no input value was passed in search using the input default
238  QString tmpFValue = inputKeyValue;
239  if (tmpFValue.isEmpty()) {
240  if (translationGroup.hasKeyword("InputDefault")) {
241  tmpFValue = (QString) translationGroup["InputDefault"];
242  }
243  else {
244  QString msg = "No value or default value to translate for ";
245  msg += "translation group [";
246  msg += translationGroupName;
247  msg += "] in file [" + p_trnsTbl.fileName() + "]";
248  throw IException(IException::Programmer, msg, _FILEINFO_);
249  }
250  }
251 
252  // Search the Translation keywords for a match to the input value
253  Pvl::ConstPvlKeywordIterator it = translationGroup.findKeyword("Translation",
254  translationGroup.begin(),
255  translationGroup.end());
256 
257  while (it != translationGroup.end()) {
258  const PvlKeyword &key = *it;
259  // compare the value from the input file to the second value of each Translation in the trans file.
260  // ignore cases for input values
261  if (QString::compare((QString) key[1], tmpFValue, Qt::CaseInsensitive) == 0) {
262  return key[0];
263  }
264  else if ((QString) key[1] == "*") {
265  if ((QString) key[0] == "*") {
266  return tmpFValue;
267  }
268  else {
269  return key[0];
270  }
271  }
272 
273  it = translationGroup.findKeyword("Translation", it + 1, translationGroup.end());
274  }
275 
276  QString msg = "Unable to find a translation value for [" +
277  translationGroupName + ", " + inputKeyValue + "] in file [" +
278  p_trnsTbl.fileName() + "]";
279 
280  throw IException(IException::Programmer, msg, _FILEINFO_);
281  }
282 
283 
301  PvlKeyword PvlTranslationTable::InputGroup(const QString translationGroupName,
302  const int inst) const {
303 
304  const PvlGroup &translationGroup = findTranslationGroup(translationGroupName);
305 
306  //bool foundLegalInputGroup = false;
307 
308  Pvl::ConstPvlKeywordIterator it = translationGroup.findKeyword("InputPosition",
309  translationGroup.begin(),
310  translationGroup.end());
311 
312  int currentInstance = 0;
313 
314  // If no InputPosition keyword exists, the answer is root
315  if (inst == 0 && it == translationGroup.end()) {
316  PvlKeyword root("InputPosition");
317  root += "ROOT";
318  return root;
319  }
320 
321  while (it != translationGroup.end()) {
322  const PvlKeyword &result = *it;
323 
324  // This check is to prevent backtracking to the old "value,value" way of
325  // doing translation file input groups for the new keyword. Flag it
326  // immediately to give a good error message.
327  if (result.size() == 1 && result[0].contains(",")) {
328  QString msg = "Keyword [InputPosition] cannot have a comma [,] in ";
329  msg += " the value [";
330  msg += result[0];
331  msg += "]";
332  throw IException(IException::Programmer, msg, _FILEINFO_);
333  }
334  else {
335  //foundLegalInputGroup = true;
336 
337  if (currentInstance == inst) {
338  return result;
339  }
340 
341  currentInstance ++;
342  }
343 
344  it = translationGroup.findKeyword("InputPosition", it + 1, translationGroup.end());
345  }
346 
347  /* Error if no containers were listed
348  if (!foundLegalInputGroup) {
349  QString msg = "No input position found for translation [";
350  msg += translationGroupName;
351  msg += "] in translation file [";
352  msg += p_trnsTbl.FileName();
353  msg += "]";
354  throw IException::Message(IException::Programmer, msg, _FILEINFO_);
355  }*/
356 
357  PvlKeyword empty;
358  return empty;
359  }
360 
361 
376  QString PvlTranslationTable::InputKeywordName(const QString translationGroupName) const {
377 
378  const PvlGroup &translationGroup = findTranslationGroup(translationGroupName);
379 
380  if (translationGroup.hasKeyword("InputKey")) return translationGroup["InputKey"];
381 
382  return "";
383  }
384 
385 
398  QString PvlTranslationTable::InputDefault(const QString translationGroupName) const {
399 
400  const PvlGroup &translationGroup = findTranslationGroup(translationGroupName);
401 
402  if (translationGroup.hasKeyword("InputDefault")) return translationGroup["InputDefault"];
403 
404  return "";
405  }
406 
407 
423  bool PvlTranslationTable::hasInputDefault(const QString translationGroupName) {
424 
425  const PvlGroup &translationGroup = findTranslationGroup(translationGroupName);
426 
427  if (translationGroup.hasKeyword("InputDefault")) return true;
428 
429  return false;
430  }
431 
432 
448  bool PvlTranslationTable::IsAuto(const QString translationGroupName) {
449 
450  const PvlGroup &translationGroup = findTranslationGroup(translationGroupName);
451 
452  if (translationGroup.hasKeyword("Auto")) return true;
453 
454  return false;
455  }
456 
457 
473  bool PvlTranslationTable::IsOptional(const QString translationGroupName) {
474 
475  const PvlGroup &translationGroup = findTranslationGroup(translationGroupName);
476 
477  if (translationGroup.hasKeyword("Optional")) return true;
478 
479  return false;
480  }
481 
482 
499  PvlKeyword PvlTranslationTable::OutputPosition(const QString translationGroupName) {
500 
501  const PvlGroup &translationGroup = findTranslationGroup(translationGroupName);
502 
503  if (!translationGroup.hasKeyword("OutputPosition")) {
504  QString msg = "Unable to find translation keyword [OutputPostion] in [" +
505  translationGroupName + "] in file [" + p_trnsTbl.fileName() + "]";
506  throw IException(IException::Programmer, msg, _FILEINFO_);
507 
508  }
509 
510  return translationGroup["OutputPosition"];
511  }
512 
513 
527  QString PvlTranslationTable::OutputName(const QString translationGroupName) {
528 
529  const PvlGroup &translationGroup = findTranslationGroup(translationGroupName);
530 
531  if (translationGroup.hasKeyword("OutputName")) {
532  return translationGroup["OutputName"];
533  }
534 
535  return "";
536  }
537 
554  const PvlGroup &PvlTranslationTable::findTranslationGroup(const QString translationGroupName) const {
555  if (!p_trnsTbl.hasGroup(translationGroupName)) {
556  QString msg = "Unable to find translation group [" + translationGroupName +
557  "] in file [" + p_trnsTbl.fileName() + "]";
558  throw IException(IException::Programmer, msg, _FILEINFO_);
559  }
560 
561  return p_trnsTbl.findGroup(translationGroupName);
562  }
563 } // end namespace isis
564 
int keywords() const
Returns the number of keywords contained in the PvlContainer.
Definition: PvlContainer.h:100
PvlKeywordIterator end()
Return the ending iterator.
Definition: PvlContainer.h:208
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
File name manipulation and expansion.
Definition: FileName.h:116
PvlKeywordIterator begin()
Return the beginning iterator.
Definition: PvlContainer.h:192
Namespace for the standard library.
QString name() const
Returns the container name.
Definition: PvlContainer.h:77
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:141
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A single keyword-value pair.
Definition: PvlKeyword.h:98
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
Container for cube-like labels.
Definition: Pvl.h:135
PvlKeyword & findKeyword(const QString &name)
Find a keyword with a specified name.
QString fileName() const
Returns the filename used to initialise the Pvl object.
Definition: PvlContainer.h:246
QString name() const
Returns the keyword name.
Definition: PvlKeyword.h:114
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
QList< PvlKeyword >::const_iterator ConstPvlKeywordIterator
The const keyword iterator.
Definition: PvlContainer.h:174
void read(const QString &file)
Loads PVL information from a stream.
Definition: Pvl.cpp:76