Isis 3 Programmer Reference
PvlToXmlTranslationManager.cpp
Go to the documentation of this file.
1 
23 
24 #include <QDebug>
25 #include <QDomDocument>
26 #include <QDomElement>
27 #include <QString>
28 
29 #include "IException.h"
30 #include "IString.h"
31 #include "Message.h"
32 #include "Pvl.h"
33 #include "PvlContainer.h"
34 #include "PvlGroup.h"
35 #include "PvlKeyword.h"
36 #include "PvlObject.h"
38 
39 using namespace std;
40 namespace Isis {
41 
51  PvlToXmlTranslationManager::PvlToXmlTranslationManager(const QString &transFile)
52  : LabelTranslationManager(transFile) {
53  }
54 
55 
65  const QString &transFile)
66  : LabelTranslationManager(transFile) {
67  m_inputLabel = inputLabel;
68  }
69 
70 
73  }
74 
75 
82  m_inputLabel = inputLabel;
83  }
84 
85 
94  vector< pair<QString, int> > PvlToXmlTranslationManager::validKeywords() const {
95 
96  vector< pair<QString, int> > validKeywords = PvlTranslationTable::validKeywords();
97  validKeywords.push_back(pair<QString, int>("OutputAttributes", -1));
98  validKeywords.push_back(pair<QString, int>("OutputSiblings", -1));
99 
100  return validKeywords;
101  }
102 
103 
119  QString PvlToXmlTranslationManager::Translate(QString transGroupName,
120  int inputIndex) {
121  const PvlContainer *con;
122  int inst = 0;
123  PvlKeyword grp;
124 
125  while((grp = InputGroup(transGroupName, inst++)).name() != "") {
126  if((con = GetContainer(grp)) != NULL) {
127  if(con->hasKeyword(InputKeywordName(transGroupName))) {
129  transGroupName, (*con)[InputKeywordName(transGroupName)][inputIndex]);
130  }
131  }
132  }
133  return PvlTranslationTable::Translate(transGroupName);
134  }
135 
136 
149  QDomElement &parentElement) {
150 
151  int inst = 0;
152  QString transGroupName = transGroup.name();
153  PvlKeyword grp = InputGroup(transGroupName, inst);
154 
155  while (grp.name() != "") {
156 
157  const PvlContainer *con = GetContainer(grp);
158  if (con != NULL) {
159  if (con->hasKeyword(InputKeywordName(transGroupName))) {
160 
161  QStringList outputName = parseSpecification(OutputName(transGroupName));
162  // Get the InputKey from the input label.
163  PvlKeyword inputKeyword = (*con)[InputKeywordName(transGroupName)];
164  // Translate input keyword value and set the qdomelement
165  // NOTE: We are assuming this is a single valued keyword since
166  // xml does not allow multiple values
167  QString untranslatedValue = inputKeyword[0];
168  QString translatedValue = PvlTranslationTable::Translate(transGroupName,
169  untranslatedValue);
170  QString units = inputKeyword.unit();
171  if (outputName.size() == 2 && outputName[0] == "att") {
172  parentElement.setAttribute(outputName[1], translatedValue);
173  if (transGroup.hasKeyword("OutputAttributes")) {
174  addAttributes(transGroup.findKeyword("OutputAttributes"), parentElement);
175  }
176  }
177  else {
178  QDomElement newElement = parentElement.ownerDocument().createElement(outputName[0]);
179  setElementValue(newElement, translatedValue, units);
180  parentElement.appendChild(newElement);
181  if (transGroup.hasKeyword("OutputAttributes")) {
182  addAttributes(transGroup.findKeyword("OutputAttributes"), newElement);
183  }
184  }
185 
186  if (transGroup.hasKeyword("OutputSiblings")) {
187  addSiblings(transGroup.findKeyword("OutputSiblings"), parentElement);
188  }
189  return;
190 
191  }
192  }
193  grp = InputGroup(transGroupName, ++inst);
194  }
195 
196  // Look for default
197  QString translatedValue = PvlTranslationTable::Translate(transGroupName, "");
198  QDomElement newElement = parentElement.ownerDocument().createElement(OutputName(transGroupName));
199  setElementValue(newElement, translatedValue);
200  parentElement.appendChild(newElement);
201  if (transGroup.hasKeyword("OutputAttributes")) {
202  addAttributes(transGroup.findKeyword("OutputAttributes"), newElement);
203  }
204  if (transGroup.hasKeyword("OutputSiblings")) {
205  addSiblings(transGroup.findKeyword("OutputSiblings"), parentElement);
206  }
207 
208  }
209 
210 
223  QDomDocument &outputLabel) {
224  m_inputLabel = inputLabel;
225  Auto(outputLabel);
226  }
227 
228 
236  void PvlToXmlTranslationManager::Auto(QDomDocument &outputLabel) {
237  Pvl pvl;
238  // Attempt to translate every group in the translation table
239  for(int i = 0; i < TranslationTable().groups(); i++) {
240  PvlGroup &g = TranslationTable().group(i);
241  if(IsAuto(g.name())) {
242  try {
243  QDomElement element = outputLabel.documentElement();
244  QDomElement *parentElement = createParentElements(g.name(), element);
245  // deal with siblings and attributes
246  doTranslation(g, *parentElement);
247  }
248  catch(IException &e) {
249  if(!IsOptional(g.name())) {
250  throw;//???
251  }
252  }
253  }
254  }
255  }
256 
257 
269  const PvlKeyword &PvlToXmlTranslationManager::InputKeyword(const QString transGroupName) const {
270 
271  int instanceNumber = 0;
272  PvlKeyword inputGroupKeyword = InputGroup(transGroupName, instanceNumber);
273  bool anInputGroupFound = false;
274 
275  while(inputGroupKeyword.name() != "") {
276  const PvlContainer *containingGroup = GetContainer(inputGroupKeyword);
277  if(containingGroup != NULL) {
278  anInputGroupFound = true;
279 
280  if(containingGroup->hasKeyword(InputKeywordName(transGroupName))) {
281  return containingGroup->findKeyword(InputKeywordName(transGroupName));
282  }
283  }
284 
285  instanceNumber ++;
286  inputGroupKeyword = InputGroup(transGroupName, instanceNumber);
287  }
288 
289  if(anInputGroupFound) {
290  QString msg = "Unable to find input keyword [" + InputKeywordName(transGroupName) +
291  "] for output name [" + transGroupName + "] in file [" +
292  TranslationTable().fileName() + "]";
294  }
295  else {
296  QString container = "";
297 
298  for(int i = 0; i < InputGroup(transGroupName).size(); i++) {
299  if(i > 0) container += ",";
300 
301  container += InputGroup(transGroupName)[i];
302  }
303 
304  QString msg = "Unable to find input group [" + container + "] for output name [" +
305  transGroupName + "] in file [" + TranslationTable().fileName() + "]";
307  }
308  }
309 
310 
319  bool PvlToXmlTranslationManager::InputHasKeyword(const QString transGroupName) {
320 
321  // Set the current position in the input label pvl
322  // by finding the input group corresponding to the output group
323  const PvlContainer *con;
324  int inst = 0;
325 
326  PvlKeyword grp;
327  while((grp = InputGroup(transGroupName, inst++)).name() != "") {
328  if((con = GetContainer(grp)) != NULL) {
329  if(con->hasKeyword(InputKeywordName(transGroupName))) return true;
330  }
331  }
332 
333  return false;
334  }
335 
336 
346 
347 
348  // Return the root container if "ROOT" is the ONLY thing in the list
349  if(inputGroup.size() == 1 &&
350  PvlKeyword::stringEqual(inputGroup[0], "ROOT")) {
351  return &m_inputLabel;
352  }
353 
354  const PvlObject *currentObject = &m_inputLabel;
355 
356  // Search for object containing our solution
357  int objectIndex;
358  for(objectIndex = 0;
359  objectIndex < inputGroup.size() - 1;
360  objectIndex ++) {
361  if(currentObject->hasObject(inputGroup[objectIndex])) {
362  currentObject = &currentObject->findObject(inputGroup[objectIndex]);
363  }
364  else {
365  return NULL;
366  }
367  }
368 
369  // Our solution can be an object or a group
370  if(currentObject->hasObject(inputGroup[objectIndex])) {
371  return &currentObject->findObject(inputGroup[objectIndex]);
372  }
373  else if(currentObject->hasGroup(inputGroup[objectIndex])) {
374  return &currentObject->findGroup(inputGroup[objectIndex]);
375  }
376  else {
377  return NULL;
378  }
379  }
380 
381 
393  QDomElement *PvlToXmlTranslationManager::createParentElements(const QString translationGroupName,
394  QDomElement &xmlRootElement) {
395 
396  // Get the OutputPosition array using the name of the translation group
397  PvlKeyword containers = OutputPosition(translationGroupName);
398 
399  QDomElement *currentElement = &xmlRootElement;
400 
401  int i = 0;
402  // Check if the root node (e.g. Product_Observational) exits in the OutputPosition values
403  // If so, skip over that OutputPosition value so we don't add it as a child of itself
404  if (containers.size() > 0 && currentElement->tagName() == containers[0]) {
405  i = 1;
406  }
407 
408  // Look at all the containers and add any missing ones or ones explicitly requested with new@
409  while (i < containers.size()) {
410 
411  // Parse current value in the OuputPosition
412  // (i.e. parse into string tokens using "@" and ":" as delimiters)
413  QStringList specifications = parseSpecification(containers[i]);
414 
415  bool addNewElement = false;
416  // After parsing, if the first token is "new", then add a new child element
417  if (specifications.size() == 2 && specifications[0] == "new") {
418  addNewElement = true;
419  }
420 
421  // Check if the specification says we need a new element
422  if (addNewElement) {
423 
424  QDomElement childElement = xmlRootElement.ownerDocument().createElement(specifications[1]);
425  *currentElement = currentElement->appendChild(childElement).toElement();
426  }
427 
428  // If the current element does not have a direct child with the name at containers[i]
429  else if (currentElement->namedItem(containers[i]).isNull()) {
430  QDomElement childElement = xmlRootElement.ownerDocument().createElement(specifications[0]);
431  *currentElement = currentElement->appendChild(childElement).toElement();
432  }
433 
434  // Otherwise, if we are not requesting a container with @new, grab the child container
435  else {
436  *currentElement = currentElement->firstChildElement(containers[i]);
437  }
438  i++;
439  }
440  return currentElement;
441  }
442 
443 
454  QDomElement &parent) {
455 
456  for (int i = 0; i < outputSiblings.size(); i++) {
457  QStringList parsedSibling;
458  parsedSibling.reserve(5);
459  parsedSibling = parseSpecification(outputSiblings[i]);
460  if (parsedSibling.size() != 2) {
461  // If the sibling does not have a tag name AND a tag value
462  QString msg = "Malformed OutputSibling [" + outputSiblings[i] + "]. OutputSiblings must" +
463  " be in the form of tag|value";
465  }
466 
467  if (parent.namedItem(parsedSibling[0]).isNull()) {
468  // parsedSibling[0] is the tag name, parsedSibling[1] is the tag value
469  QDomElement childElement = parent.ownerDocument().createElement(parsedSibling[0]);
470  setElementValue(childElement, parsedSibling[1]);
471  parent.appendChild(childElement).toElement();;
472  }
473  }
474  }
475 
476 
487  QDomElement &element) {
488  QStringList parsedAttribute;
489 
490  for (int i = 0; i < outputAttributes.size(); i++) {
491  parsedAttribute = parseSpecification(outputAttributes[i]);
492 
493  if (parsedAttribute.size() != 2) {
494  QString msg = "Malformed output attribute [" + outputAttributes[i] +
495  "]. OutputAttributes must be in the form of att@attribute_name|value";
497  }
498  element.setAttribute(parsedAttribute[0], parsedAttribute[1]);
499  }
500  }
501 
502 
513  void PvlToXmlTranslationManager::addElement(QDomElement &parent,
514  QString name,
515  QString value,
516  QString units) {
517  QDomElement newElement = parent.ownerDocument().createElement(name);
518  setElementValue(newElement, value, units);
519  // append element to parent node???
520  parent.appendChild(newElement).toElement();;
521  }
522 
523 
532  QString value,
533  QString units) {
534  QDomText valueText = element.ownerDocument().createTextNode(value);
535  // append value to element???
536  element.appendChild(valueText);
537 
538  if (units != "") {
539  element.setAttribute("unit", units);
540  }
541  }
542 
543 
552  QString value,
553  QString units) {
554  element.firstChild().setNodeValue(value);
555  if (units != "") {
556  element.setAttribute("unit", units);
557  }
558  }
559 } // end namespace isis
560 
virtual ~PvlToXmlTranslationManager()
Destroys the TranslationManager object.
virtual QString Translate(QString translationGroupName, int inputIndex=0)
Returns a translated value.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
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:373
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
Contains more than one keyword-value pair.
Definition: PvlContainer.h:63
static void addElement(QDomElement &parent, QString name, QString value, QString units="")
Add a QDomElement to the given parent with the indicated value and units.
virtual QStringList parseSpecification(QString specification) const
Parses and validates a dependency specification.
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:286
PvlKeyword OutputPosition(const QString translationGroupName)
Retrieves the OutputPosition PvlKeyword for the translation group with the given name.
Namespace for the standard library.
bool hasGroup(const QString &name) const
Returns a boolean value based on whether the object has the specified group or not.
Definition: PvlObject.h:222
void addAttributes(PvlKeyword something, QDomElement &parent)
Take in the outputAttributes PvlKeyword and add each attribute to the appropriate element given as an...
static bool stringEqual(const QString &string1, const QString &string2)
Checks to see if two QStrings are equal.
Definition: PvlKeyword.cpp:551
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
PvlToXmlTranslationManager(const QString &transFile)
Constructs and initializes a TranslationManager object from given the Pvl translation file...
QDomElement * createParentElements(const QString translationGroupName, QDomElement &xml)
Read the OutputPosition for the translation group name passed and create any parent elements specifie...
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:335
QString Translate(const QString translationGroupName, const QString inputKeyValue="") const
Translates a single output value from the given translation group name and input value.
QString name() const
Returns the container name.
Definition: PvlContainer.h:77
static void resetElementValue(QDomElement &element, QString value, QString units="")
Reset the QDomElement&#39;s value, and units, if units != "".
virtual QString InputKeywordName(const QString translationGroupName) const
Returns the input keyword name from the translation table corresponding to the output name argument...
void doTranslation(PvlGroup transGroup, QDomElement &parent)
Translate the requested output name to output values using the input name and values or default value...
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...
QString OutputName(const QString translationGroupName)
Retrieves a string containing the value of the OutputName keyword for the translation group with the ...
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:141
Pvl & TranslationTable()
Protected accessor for pvl translation table passed into class.
virtual std::vector< std::pair< QString, int > > validKeywords() const
Returns a vector of valid keyword names and their sizes.
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
virtual std::vector< std::pair< QString, int > > validKeywords() const
Returns a vector of valid keyword names and their sizes.
static void setElementValue(QDomElement &element, QString value, QString units="")
Set the QDomElement&#39;s value, and units, if units != "".
void SetLabel(Pvl &inputLabel)
Internalizes a Pvl formatted label for translation.
Container for cube-like labels.
Definition: Pvl.h:135
virtual bool InputHasKeyword(const QString translationGroupName)
Indicates if the input keyword corresponding to the output name exists in the label.
PvlKeyword & findKeyword(const QString &name)
Find a keyword with a specified name.
PvlGroup & group(const int index)
Return the group at the specified index.
Definition: PvlObject.cpp:423
void addSiblings(PvlKeyword outputSiblings, QDomElement &parent)
Take in outputSiblings PvlKeyword and turn each sibling into its corresponding QDomElement.
Pvl m_inputLabel
A Pvl object for the input label file.
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
void Auto(QDomDocument &outputLabel)
Automatically translate all the output names found in the translation table.
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
bool IsOptional(const QString translationGroupName)
Determines whether the translation group is optional.
Allows applications to translate simple text files.
int groups() const
Returns the number of groups contained.
Definition: PvlObject.h:87
virtual const PvlKeyword & InputKeyword(const QString translationGroupName) const
Uses the translation file group name to find the input label&#39;s PvlKeyword that corresponds to the Inp...
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:74
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...
bool IsAuto(const QString translationGroupName)
Determines whether the given group should be automatically translated.