Isis 3 Programmer Reference
PvlToXmlTranslationManager.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "LabelTranslationManager.h"
8 
9 #include <QDebug>
10 #include <QDomDocument>
11 #include <QDomElement>
12 #include <QString>
13 
14 #include "IException.h"
15 #include "IString.h"
16 #include "Message.h"
17 #include "Pvl.h"
18 #include "PvlContainer.h"
19 #include "PvlGroup.h"
20 #include "PvlKeyword.h"
21 #include "PvlObject.h"
22 #include "PvlToXmlTranslationManager.h"
23 
24 using namespace std;
25 namespace Isis {
26 
36  PvlToXmlTranslationManager::PvlToXmlTranslationManager(const QString &transFile)
37  : LabelTranslationManager(transFile) {
38  }
39 
40 
50  const QString &transFile)
51  : LabelTranslationManager(transFile) {
52  m_inputLabel = inputLabel;
53  }
54 
55 
58  }
59 
60 
67  m_inputLabel = inputLabel;
68  }
69 
70 
79  vector< pair<QString, int> > PvlToXmlTranslationManager::validKeywords() const {
80 
81  vector< pair<QString, int> > validKeywords = PvlTranslationTable::validKeywords();
82  validKeywords.push_back(pair<QString, int>("OutputAttributes", -1));
83  validKeywords.push_back(pair<QString, int>("OutputSiblings", -1));
84 
85  return validKeywords;
86  }
87 
88 
104  QString PvlToXmlTranslationManager::Translate(QString transGroupName,
105  int inputIndex) {
106  const PvlContainer *con;
107  int inst = 0;
108  PvlKeyword grp;
109 
110  while((grp = InputGroup(transGroupName, inst++)).name() != "") {
111  if((con = GetContainer(grp)) != NULL) {
112  if(con->hasKeyword(InputKeywordName(transGroupName))) {
114  transGroupName, (*con)[InputKeywordName(transGroupName)][inputIndex]);
115  }
116  }
117  }
118  return PvlTranslationTable::Translate(transGroupName);
119  }
120 
121 
134  QDomElement &parentElement) {
135 
136  int inst = 0;
137  QString transGroupName = transGroup.name();
138  PvlKeyword grp = InputGroup(transGroupName, inst);
139 
140  while (grp.name() != "") {
141 
142  const PvlContainer *con = GetContainer(grp);
143  if (con != NULL) {
144  if (con->hasKeyword(InputKeywordName(transGroupName))) {
145 
146  QStringList outputName = parseSpecification(OutputName(transGroupName));
147  // Get the InputKey from the input label.
148  PvlKeyword inputKeyword = (*con)[InputKeywordName(transGroupName)];
149  // Translate input keyword value and set the qdomelement
150  // NOTE: We are assuming this is a single valued keyword since
151  // xml does not allow multiple values
152  QString untranslatedValue = inputKeyword[0];
153  QString translatedValue = PvlTranslationTable::Translate(transGroupName,
154  untranslatedValue);
155  QString units = inputKeyword.unit();
156  if (outputName.size() == 2 && outputName[0] == "att") {
157  parentElement.setAttribute(outputName[1], translatedValue);
158  if (transGroup.hasKeyword("OutputAttributes")) {
159  addAttributes(transGroup.findKeyword("OutputAttributes"), parentElement);
160  }
161  }
162  else {
163  QDomElement newElement = parentElement.ownerDocument().createElement(outputName[0]);
164  setElementValue(newElement, translatedValue, units);
165  parentElement.appendChild(newElement);
166  if (transGroup.hasKeyword("OutputAttributes")) {
167  addAttributes(transGroup.findKeyword("OutputAttributes"), newElement);
168  }
169  }
170 
171  if (transGroup.hasKeyword("OutputSiblings")) {
172  addSiblings(transGroup.findKeyword("OutputSiblings"), parentElement);
173  }
174  return;
175 
176  }
177  }
178  grp = InputGroup(transGroupName, ++inst);
179  }
180 
181  // Look for default
182  QString translatedValue = PvlTranslationTable::Translate(transGroupName, "");
183  QDomElement newElement = parentElement.ownerDocument().createElement(OutputName(transGroupName));
184  setElementValue(newElement, translatedValue);
185  parentElement.appendChild(newElement);
186  if (transGroup.hasKeyword("OutputAttributes")) {
187  addAttributes(transGroup.findKeyword("OutputAttributes"), newElement);
188  }
189  if (transGroup.hasKeyword("OutputSiblings")) {
190  addSiblings(transGroup.findKeyword("OutputSiblings"), parentElement);
191  }
192 
193  }
194 
195 
208  QDomDocument &outputLabel) {
209  m_inputLabel = inputLabel;
210  Auto(outputLabel);
211  }
212 
213 
221  void PvlToXmlTranslationManager::Auto(QDomDocument &outputLabel) {
222  Pvl pvl;
223  // Attempt to translate every group in the translation table
224  for(int i = 0; i < TranslationTable().groups(); i++) {
225  PvlGroup &g = TranslationTable().group(i);
226  if(IsAuto(g.name())) {
227  try {
228  QDomElement element = outputLabel.documentElement();
229  QDomElement *parentElement = createParentElements(g.name(), element);
230  // deal with siblings and attributes
231  doTranslation(g, *parentElement);
232  }
233  catch(IException &e) {
234  if(!IsOptional(g.name())) {
235  throw;//???
236  }
237  }
238  }
239  }
240  }
241 
242 
254  const PvlKeyword &PvlToXmlTranslationManager::InputKeyword(const QString transGroupName) const {
255 
256  int instanceNumber = 0;
257  PvlKeyword inputGroupKeyword = InputGroup(transGroupName, instanceNumber);
258  bool anInputGroupFound = false;
259 
260  while(inputGroupKeyword.name() != "") {
261  const PvlContainer *containingGroup = GetContainer(inputGroupKeyword);
262  if(containingGroup != NULL) {
263  anInputGroupFound = true;
264 
265  if(containingGroup->hasKeyword(InputKeywordName(transGroupName))) {
266  return containingGroup->findKeyword(InputKeywordName(transGroupName));
267  }
268  }
269 
270  instanceNumber ++;
271  inputGroupKeyword = InputGroup(transGroupName, instanceNumber);
272  }
273 
274  if(anInputGroupFound) {
275  QString msg = "Unable to find input keyword [" + InputKeywordName(transGroupName) +
276  "] for output name [" + transGroupName + "] in file [" +
277  TranslationTable().fileName() + "]";
278  throw IException(IException::Programmer, msg, _FILEINFO_);
279  }
280  else {
281  QString container = "";
282 
283  for(int i = 0; i < InputGroup(transGroupName).size(); i++) {
284  if(i > 0) container += ",";
285 
286  container += InputGroup(transGroupName)[i];
287  }
288 
289  QString msg = "Unable to find input group [" + container + "] for output name [" +
290  transGroupName + "] in file [" + TranslationTable().fileName() + "]";
291  throw IException(IException::Programmer, msg, _FILEINFO_);
292  }
293  }
294 
295 
304  bool PvlToXmlTranslationManager::InputHasKeyword(const QString transGroupName) {
305 
306  // Set the current position in the input label pvl
307  // by finding the input group corresponding to the output group
308  const PvlContainer *con;
309  int inst = 0;
310 
311  PvlKeyword grp;
312  while((grp = InputGroup(transGroupName, inst++)).name() != "") {
313  if((con = GetContainer(grp)) != NULL) {
314  if(con->hasKeyword(InputKeywordName(transGroupName))) return true;
315  }
316  }
317 
318  return false;
319  }
320 
321 
331 
332 
333  // Return the root container if "ROOT" is the ONLY thing in the list
334  if(inputGroup.size() == 1 &&
335  PvlKeyword::stringEqual(inputGroup[0], "ROOT")) {
336  return &m_inputLabel;
337  }
338 
339  const PvlObject *currentObject = &m_inputLabel;
340 
341  // Search for object containing our solution
342  int objectIndex;
343  for(objectIndex = 0;
344  objectIndex < inputGroup.size() - 1;
345  objectIndex ++) {
346  if(currentObject->hasObject(inputGroup[objectIndex])) {
347  currentObject = &currentObject->findObject(inputGroup[objectIndex]);
348  }
349  else {
350  return NULL;
351  }
352  }
353 
354  // Our solution can be an object or a group
355  if(currentObject->hasObject(inputGroup[objectIndex])) {
356  return &currentObject->findObject(inputGroup[objectIndex]);
357  }
358  else if(currentObject->hasGroup(inputGroup[objectIndex])) {
359  return &currentObject->findGroup(inputGroup[objectIndex]);
360  }
361  else {
362  return NULL;
363  }
364  }
365 
366 
378  QDomElement *PvlToXmlTranslationManager::createParentElements(const QString translationGroupName,
379  QDomElement &xmlRootElement) {
380 
381  // Get the OutputPosition array using the name of the translation group
382  PvlKeyword containers = OutputPosition(translationGroupName);
383 
384  QDomElement *currentElement = &xmlRootElement;
385 
386  int i = 0;
387  // Check if the root node (e.g. Product_Observational) exits in the OutputPosition values
388  // If so, skip over that OutputPosition value so we don't add it as a child of itself
389  if (containers.size() > 0 && currentElement->tagName() == containers[0]) {
390  i = 1;
391  }
392 
393  // Look at all the containers and add any missing ones or ones explicitly requested with new@
394  while (i < containers.size()) {
395 
396  // Parse current value in the OuputPosition
397  // (i.e. parse into string tokens using "@" and ":" as delimiters)
398  QStringList specifications = parseSpecification(containers[i]);
399 
400  bool addNewElement = false;
401  // After parsing, if the first token is "new", then add a new child element
402  if (specifications.size() == 2 && specifications[0] == "new") {
403  addNewElement = true;
404  }
405 
406  // Check if the specification says we need a new element
407  if (addNewElement) {
408 
409  QDomElement childElement = xmlRootElement.ownerDocument().createElement(specifications[1]);
410  *currentElement = currentElement->appendChild(childElement).toElement();
411  }
412 
413  // If the current element does not have a direct child with the name at containers[i]
414  else if (currentElement->namedItem(containers[i]).isNull()) {
415  QDomElement childElement = xmlRootElement.ownerDocument().createElement(specifications[0]);
416  *currentElement = currentElement->appendChild(childElement).toElement();
417  }
418 
419  // Otherwise, if we are not requesting a container with @new, grab the child container
420  else {
421  *currentElement = currentElement->firstChildElement(containers[i]);
422  }
423  i++;
424  }
425  return currentElement;
426  }
427 
428 
439  QDomElement &parent) {
440 
441  for (int i = 0; i < outputSiblings.size(); i++) {
442  QStringList parsedSibling;
443  parsedSibling.reserve(5);
444  parsedSibling = parseSpecification(outputSiblings[i]);
445  if (parsedSibling.size() != 2) {
446  // If the sibling does not have a tag name AND a tag value
447  QString msg = "Malformed OutputSibling [" + outputSiblings[i] + "]. OutputSiblings must" +
448  " be in the form of tag|value";
449  throw IException(IException::Programmer, msg, _FILEINFO_);
450  }
451 
452  if (parent.namedItem(parsedSibling[0]).isNull()) {
453  // parsedSibling[0] is the tag name, parsedSibling[1] is the tag value
454  QDomElement childElement = parent.ownerDocument().createElement(parsedSibling[0]);
455  setElementValue(childElement, parsedSibling[1]);
456  parent.appendChild(childElement).toElement();;
457  }
458  }
459  }
460 
461 
472  QDomElement &element) {
473  QStringList parsedAttribute;
474 
475  for (int i = 0; i < outputAttributes.size(); i++) {
476  parsedAttribute = parseSpecification(outputAttributes[i]);
477 
478  if (parsedAttribute.size() != 2) {
479  QString msg = "Malformed output attribute [" + outputAttributes[i] +
480  "]. OutputAttributes must be in the form of att@attribute_name|value";
481  throw IException(IException::Programmer,msg ,_FILEINFO_);
482  }
483  element.setAttribute(parsedAttribute[0], parsedAttribute[1]);
484  }
485  }
486 
487 
498  void PvlToXmlTranslationManager::addElement(QDomElement &parent,
499  QString name,
500  QString value,
501  QString units) {
502  QDomElement newElement = parent.ownerDocument().createElement(name);
503  setElementValue(newElement, value, units);
504  // append element to parent node???
505  parent.appendChild(newElement).toElement();;
506  }
507 
508 
517  QString value,
518  QString units) {
519  QDomText valueText = element.ownerDocument().createTextNode(value);
520  // append value to element???
521  element.appendChild(valueText);
522 
523  if (units != "") {
524  element.setAttribute("unit", units);
525  }
526  }
527 
528 
537  QString value,
538  QString units) {
539  element.firstChild().setNodeValue(value);
540  if (units != "") {
541  element.setAttribute("unit", units);
542  }
543  }
544 } // end namespace isis
545 
Isis::LabelTranslationManager::parseSpecification
virtual QStringList parseSpecification(QString specification) const
Parses and validates a dependency specification.
Definition: LabelTranslationManager.cpp:172
Isis::PvlToXmlTranslationManager::addSiblings
void addSiblings(PvlKeyword outputSiblings, QDomElement &parent)
Take in outputSiblings PvlKeyword and turn each sibling into its corresponding QDomElement.
Definition: PvlToXmlTranslationManager.cpp:438
Isis::PvlKeyword::name
QString name() const
Returns the keyword name.
Definition: PvlKeyword.h:98
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::PvlObject::group
PvlGroup & group(const int index)
Return the group at the specified index.
Definition: PvlObject.cpp:452
Isis::PvlTranslationTable::validKeywords
virtual std::vector< std::pair< QString, int > > validKeywords() const
Returns a vector of valid keyword names and their sizes.
Definition: PvlTranslationTable.cpp:179
Isis::PvlObject
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:61
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::PvlToXmlTranslationManager::addAttributes
void addAttributes(PvlKeyword something, QDomElement &parent)
Take in the outputAttributes PvlKeyword and add each attribute to the appropriate element given as an...
Definition: PvlToXmlTranslationManager.cpp:471
Isis::PvlToXmlTranslationManager::Translate
virtual QString Translate(QString translationGroupName, int inputIndex=0)
Returns a translated value.
Definition: PvlToXmlTranslationManager.cpp:104
Isis::PvlToXmlTranslationManager::doTranslation
void doTranslation(PvlGroup transGroup, QDomElement &parent)
Translate the requested output name to output values using the input name and values or default value...
Definition: PvlToXmlTranslationManager.cpp:133
Isis::PvlObject::groups
int groups() const
Returns the number of groups contained.
Definition: PvlObject.h:75
Isis::PvlTranslationTable::OutputName
QString OutputName(const QString translationGroupName)
Retrieves a string containing the value of the OutputName keyword for the translation group with the ...
Definition: PvlTranslationTable.cpp:511
Isis::PvlObject::hasGroup
bool hasGroup(const QString &name) const
Returns a boolean value based on whether the object has the specified group or not.
Definition: PvlObject.h:210
Isis::PvlToXmlTranslationManager::addElement
static void addElement(QDomElement &parent, QString name, QString value, QString units="")
Add a QDomElement to the given parent with the indicated value and units.
Definition: PvlToXmlTranslationManager.cpp:498
Isis::PvlToXmlTranslationManager::validKeywords
virtual std::vector< std::pair< QString, int > > validKeywords() const
Returns a vector of valid keyword names and their sizes.
Definition: PvlToXmlTranslationManager.cpp:79
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::PvlToXmlTranslationManager::~PvlToXmlTranslationManager
virtual ~PvlToXmlTranslationManager()
Destroys the TranslationManager object.
Definition: PvlToXmlTranslationManager.cpp:57
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
QStringList
Isis::PvlToXmlTranslationManager::createParentElements
QDomElement * createParentElements(const QString translationGroupName, QDomElement &xml)
Read the OutputPosition for the translation group name passed and create any parent elements specifie...
Definition: PvlToXmlTranslationManager.cpp:378
Isis::PvlToXmlTranslationManager::setElementValue
static void setElementValue(QDomElement &element, QString value, QString units="")
Set the QDomElement's value, and units, if units != "".
Definition: PvlToXmlTranslationManager.cpp:516
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::PvlToXmlTranslationManager::InputHasKeyword
virtual bool InputHasKeyword(const QString translationGroupName)
Indicates if the input keyword corresponding to the output name exists in the label.
Definition: PvlToXmlTranslationManager.cpp:304
Isis::PvlToXmlTranslationManager::SetLabel
void SetLabel(Pvl &inputLabel)
Internalizes a Pvl formatted label for translation.
Definition: PvlToXmlTranslationManager.cpp:66
Isis::PvlToXmlTranslationManager::resetElementValue
static void resetElementValue(QDomElement &element, QString value, QString units="")
Reset the QDomElement's value, and units, if units != "".
Definition: PvlToXmlTranslationManager.cpp:536
Isis::PvlTranslationTable::OutputPosition
PvlKeyword OutputPosition(const QString translationGroupName)
Retrieves the OutputPosition PvlKeyword for the translation group with the given name.
Definition: PvlTranslationTable.cpp:483
Isis::LabelTranslationManager
Allows applications to translate simple text files.
Definition: LabelTranslationManager.h:43
Isis::PvlObject::findObject
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:274
Isis::PvlToXmlTranslationManager::PvlToXmlTranslationManager
PvlToXmlTranslationManager(const QString &transFile)
Constructs and initializes a TranslationManager object from given the Pvl translation file.
Definition: PvlToXmlTranslationManager.cpp:36
Isis::PvlContainer::fileName
QString fileName() const
Returns the filename used to initialise the Pvl object.
Definition: PvlContainer.h:232
Isis::PvlContainer::name
QString name() const
Returns the container name.
Definition: PvlContainer.h:63
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::PvlTranslationTable::Translate
QString Translate(const QString translationGroupName, const QString inputKeyValue="") const
Translates a single output value from the given translation group name and input value.
Definition: PvlTranslationTable.cpp:216
Isis::PvlObject::hasObject
bool hasObject(const QString &name) const
Returns a boolean value based on whether the object exists in the current PvlObject or not.
Definition: PvlObject.h:323
Isis::PvlTranslationTable::InputKeywordName
virtual QString InputKeywordName(const QString translationGroupName) const
Returns the input keyword name from the translation table corresponding to the output name argument.
Definition: PvlTranslationTable.cpp:360
Isis::PvlToXmlTranslationManager::GetContainer
virtual const PvlContainer * GetContainer(const PvlKeyword &inputGroup) const
Return a container from the input label with the path given by the "InputPosition" keyword of the tra...
Definition: PvlToXmlTranslationManager.cpp:330
Isis::PvlTranslationTable::InputGroup
virtual PvlKeyword InputGroup(const QString translationGroupName, const int inst=0) const
Returns the input group name from the translation table corresponding to the output name argument.
Definition: PvlTranslationTable.cpp:285
Isis::PvlTranslationTable::IsAuto
bool IsAuto(const QString translationGroupName)
Determines whether the given group should be automatically translated.
Definition: PvlTranslationTable.cpp:432
Isis::IException::Programmer
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:146
std
Namespace for the standard library.
Isis::PvlKeyword::size
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:125
Isis::PvlTranslationTable::IsOptional
bool IsOptional(const QString translationGroupName)
Determines whether the translation group is optional.
Definition: PvlTranslationTable.cpp:457
Isis::PvlKeyword::unit
QString unit(const int index=0) const
Returns the units of measurement of the element of the array of values for the object at the specifie...
Definition: PvlKeyword.cpp:357
Isis::PvlContainer::findKeyword
PvlKeyword & findKeyword(const QString &name)
Find a keyword with a specified name.
Definition: PvlContainer.cpp:62
Isis::PvlToXmlTranslationManager::Auto
void Auto(QDomDocument &outputLabel)
Automatically translate all the output names found in the translation table.
Definition: PvlToXmlTranslationManager.cpp:221
Isis::PvlContainer
Contains more than one keyword-value pair.
Definition: PvlContainer.h:49
Isis::PvlKeyword::stringEqual
static bool stringEqual(const QString &string1, const QString &string2)
Checks to see if two QStrings are equal.
Definition: PvlKeyword.cpp:535
Isis::PvlToXmlTranslationManager::InputKeyword
virtual const PvlKeyword & InputKeyword(const QString translationGroupName) const
Uses the translation file group name to find the input label's PvlKeyword that corresponds to the Inp...
Definition: PvlToXmlTranslationManager.cpp:254
Isis::PvlToXmlTranslationManager::m_inputLabel
Pvl m_inputLabel
A Pvl object for the input label file.
Definition: PvlToXmlTranslationManager.h:92
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::PvlTranslationTable::TranslationTable
Pvl & TranslationTable()
Protected accessor for pvl translation table passed into class.
Definition: PvlTranslationTable.cpp:62