Commit 3ad5e2a6 authored by Kristin Berry's avatar Kristin Berry
Browse files

PROG: Updated XmlToPvlTranslationManager with small coding-standards changes...

PROG: Updated XmlToPvlTranslationManager with small coding-standards changes and expanded unitTest to increase code-coverage. Fixes #5167

git-svn-id: http://subversion.wr.usgs.gov/repos/prog/isis3/trunk@8184 41f8697f-d340-4b68-9986-7bafba869bb8
parent aff785d9
Loading
Loading
Loading
Loading
+42 −92
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "PvlObject.h"
#include "XmlToPvlTranslationManager.h"


using namespace std;
namespace Isis {

@@ -55,6 +56,7 @@ namespace Isis {
    AddTable(transFile);
  }


  /**
   * Constructs and initializes an XmlToPvlTranslationManager object from the given
   * input stream. If this constructor is used, the user will need to set the
@@ -138,6 +140,7 @@ namespace Isis {
    return validKeywords;
  }


  /**
   * Returns a translated value. The output name is used to find the input
   * group, keyword, default and tranlations in the translation table. If the
@@ -167,7 +170,8 @@ namespace Isis {
   * @throws IException::Unknown "Could not find an input value or default value."
   * @throws IException::Unknown "Input element does not have the named attribute."
   */
  QString XmlToPvlTranslationManager::Translate(QString outputName, int index) {
  QString XmlToPvlTranslationManager::Translate(QString outputName, 
                                                int index) {
    try {
    if (index != 0) {
      QString msg = "Cannot translate value at index [" + toString(index) +
@@ -362,7 +366,11 @@ namespace Isis {
      cout << endl << "Testing dependencies:" << endl;
    }
    for (int i = 0; i < dependencies.size(); i++) {
      QStringList specification = parseDependency(dependencies[i]);
      QStringList specification = parseSpecification(dependencies[i]);

      if (specification.size() != 3) { // the specification is not a dependancy
        return true;
      }
      if (isDebug) {
        cout << endl << "Testing dependency number " << toString(i+1) << endl;
        cout << "  Specification:    " << dependencies[i] << endl;
@@ -419,65 +427,6 @@ namespace Isis {
  }


  /**
   * Parses and validates a dependency specification.
   * 
   * @param specification The dependency specification string.
   * 
   * @return @b QStringList The dependency split into 3 components
   *                        <ol>
   *                          <li>the type (att or tag)</li>
   *                          <li>the name of what to check</li>
   *                          <li>the value to check for</li>
   *                        </ol>
   * 
   * @throws IException::Unknown "Malformed dependency specification."
   * @throws IException::Unknown "Specification does not have two components
   *                              separated by [@], the type of dependency and
   *                              the name-value pair.
   * @throws IException::Unknown "Dependency type specification is invalid.
   *                              Valid types are [att] and [tag]"
   * @throws IException::Unknown "Name-value specification does not have two
   *                              components separated by [:]."
   * 
   * @see XmlToPvlTranslationManager::checkDependencies
   */
  QStringList XmlToPvlTranslationManager::parseDependency(QString specification) const {

    QStringList parsedSpecification;

    try {
      QStringList typeSplit = specification.split("@", QString::SkipEmptyParts);
      if (typeSplit.size() != 2) {
        QString msg = "Specification does not have two components separated "
                      "by [@], the type of dependency and the name-value pair.";
        throw IException(IException::Unknown, msg, _FILEINFO_);
      }
      if (typeSplit[0].toLower() != "att" &&
          typeSplit[0].toLower() != "tag") {
        QString msg = "Dependency type specification [" + typeSplit[0] +
                      "] is invalid. Valid types are [att] and [tag]";
        throw IException(IException::Unknown, msg, _FILEINFO_);
      }
      parsedSpecification.append(typeSplit[0].toLower());

      QStringList nameValueSplit = typeSplit[1].split(":", QString::SkipEmptyParts);
      if (nameValueSplit.size() != 2) {
        QString msg = "Name-value specification [" + typeSplit[1] + "] does "
                      "not have two components separated by [:].";
        throw IException(IException::Unknown, msg, _FILEINFO_);
      }
      parsedSpecification.append(nameValueSplit);
    }
    catch (IException &e) {
      QString msg = "Malformed dependency specification [" + specification + "].";
      throw IException(e, IException::Unknown, msg, _FILEINFO_);
    }

    return parsedSpecification;
  }


  /**
   * Automatically translate all the output names flagged with the Auto keyword
   * in the translation table and store the translated key, value pairs in the
@@ -486,7 +435,8 @@ namespace Isis {
   * @param inputLabel The input label file to be translated.
   * @param outputLabel The output translated Pvl.
   */
  void XmlToPvlTranslationManager::Auto(FileName &inputLabel, Pvl &outputLabel) {
  void XmlToPvlTranslationManager::Auto(FileName &inputLabel, 
                                        Pvl &outputLabel) {
    parseFile(inputLabel);
    Auto(outputLabel);
  }
+2 −4
Original line number Diff line number Diff line
@@ -116,14 +116,13 @@ namespace Isis {
   *
   * @internal
   *  @history 2017-01-12 Jeannie Backer - Original version. Adapted from
   *                          PvlToPvlTranslationManager class. Fixes #4584.
   *                          PvlTranslationManager class. Fixes #4584.
   *  @history 2017-01-13 Jeannie Backer and Jesse Mapel - Initial Translate
   *                          and Auto design. Added dependencies for uniquely
   *                          identifying input elements. Fixes #4584.
   *  @history 2017-01-18 Jesse Mapel - Updated documentation and error messages. Fixes #4584.
   *  @history 2017-01-25 Jesse Mapel - Created unit test. Fixes #4584.
   *  @history 2017-05-30 Makayla Shepherd - Renamed from XmlTranslationManager to
   *                          XmlToPvlTranslationManager. Fixes #4889.
   *  @history 2017-05-26 Makayla Shepherd - Renamed XmlToPvlTranslationManager.
   */
  class XmlToPvlTranslationManager : public LabelTranslationManager {
    public:
@@ -152,7 +151,6 @@ namespace Isis {
    protected:
      virtual std::vector< std::pair<QString, int> > validKeywords() const;
      bool checkDependencies(QDomElement element, PvlKeyword dependencies, bool isDebug) const;
      QStringList parseDependency(QString specification) const;
      void parseFile(const FileName &xmlFileName);

    private:
+392 −7
Original line number Diff line number Diff line
@@ -4,6 +4,14 @@ Testing Translate method

Translation of InstrumentIfovWithUnits: 1.140e-005

Testing file-based constructor

Testing stream-only constructor

Testing constructor which uses an input label and translation file

Testing constructor which uses an input label and translation file

Testing Auto method


@@ -373,6 +381,387 @@ Group = CoreCube
End_Group
End

Testing Auto method with input and output labels


          ====================          

Translating output keyword: Version

Translation group:
Group = Version
  Auto           = Null
  Debug          = Null
  InputPosition  = Identification_Area
  InputKey       = version_id
  OutputPosition = (group, instrument)
  OutputName     = Version
  Translation    = (*, *)
End_Group


Finding input element:

Product_Observational
  Identification_Area
    version_id

Testing dependencies:

Translating input value: UNK

          ====================          

Translating output keyword: Host

Translation group:
Group = Host
  Auto           = Null
  Debug          = Null
  InputPosition  = (Observation_Area, Investigation_Area)
  InputKey       = Instrument_Host_Id
  OutputPosition = (group, instrument)
  OutputName     = Host
  Translation    = (*, *)
End_Group


Finding input element:

Product_Observational
  Observation_Area
    Investigation_Area
      Instrument_Host_Id

Testing dependencies:

Translating input value: TGO

          ====================          

Translating output keyword: BandWidth

Translation group:
Group = BandWidth
  Auto              = Null
  Debug             = Null
  InputPosition     = Observation_Area
  InputKey          = Science_Facets
  InputKeyAttribute = bandwidth
  OutputPosition    = (group, instrument)
  OutputName        = BandWidth
  Translation       = (*, *)
End_Group


Finding input element:

Product_Observational
  Observation_Area
    Science_Facets

Testing dependencies:

Translating input value: Broad

          ====================          

Translating output keyword: SpacecraftName

Translation group:
Group = SpacecraftName
  Auto                 = Null
  Debug                = Null
  InputPosition        = (Observation_Area, Observing_System,
                          Observing_System_Component)
  InputKey             = name
  InputKeyDependencies = tag@type:Spacecraft
  OutputPosition       = (group, instrument)
  OutputName           = SpacecraftName
  Translation          = (*, *)
End_Group


Finding input element:

Product_Observational
  Observation_Area
    Observing_System
      Observing_System_Component
        name

Testing dependencies:

Testing dependency number 1
  Specification:    tag@type:Spacecraft

  Dependency type:  tag
  Dependency name:  type
  Dependency value: Spacecraft

  Tag name:         type
  Tag value:        Spacecraft

Translating input value: TGO

          ====================          

Translating output keyword: InstrumentId

Translation group:
Group = InstrumentId
  Auto                 = Null
  Debug                = Null
  InputPosition        = (Observation_Area, Observing_System,
                          Observing_System_Component)
  InputKey             = name
  InputKeyDependencies = tag@type:Instrument
  OutputPosition       = (group, instrument)
  OutputName           = InstrumentId
  Translation          = (*, *)
End_Group


Finding input element:

Product_Observational
  Observation_Area
    Observing_System
      Observing_System_Component
        name

Testing dependencies:

Testing dependency number 1
  Specification:    tag@type:Instrument

  Dependency type:  tag
  Dependency name:  type
  Dependency value: Instrument

  Tag name:         type
  Tag value:        Spacecraft

Dependencies failed, checking next candidate.

Testing dependencies:

Testing dependency number 1
  Specification:    tag@type:Instrument

  Dependency type:  tag
  Dependency name:  type
  Dependency value: Instrument

  Tag name:         type
  Tag value:        JunkComponent

Dependencies failed, checking next candidate.

Testing dependencies:

Testing dependency number 1
  Specification:    tag@type:Instrument

  Dependency type:  tag
  Dependency name:  type
  Dependency value: Instrument

  Tag name:         type
  Tag value:        Instrument

Translating input value: CaSSIS

          ====================          

Translating output keyword: OnboardImageAcquisitionTimeUTC

Translation group:
Group = OnboardImageAcquisitionTimeUTC
  Auto                 = Null
  Debug                = Null
  InputPosition        = (CaSSIS_Header, DERIVED_HEADER_DATA)
  InputKey             = OnboardImageAcquisitionTime
  InputKeyDependencies = att@Time_Base:UTC
  OutputPosition       = (group, instrument)
  OutputName           = OnboardImageAcquisitionTimeUTC
  Translation          = (*, *)
End_Group


Finding input element:

Product_Observational
  CaSSIS_Header
    DERIVED_HEADER_DATA
      OnboardImageAcquisitionTime

Testing dependencies:

Testing dependency number 1
  Specification:    att@Time_Base:UTC

  Dependency type:  att
  Dependency name:  Time_Base
  Dependency value: UTC

  Attribute name:   Time_Base  Attribute value:  UTC

Translating input value: 2016-11-26T23:24:52.080

          ====================          

Translating output keyword: OnboardImageAcquisitionTimeET

Translation group:
Group = OnboardImageAcquisitionTimeET
  Auto                 = Null
  Debug                = Null
  InputPosition        = (CaSSIS_Header, DERIVED_HEADER_DATA)
  InputKey             = OnboardImageAcquisitionTime
  InputKeyDependencies = att@Time_Base:ET
  OutputPosition       = (group, instrument)
  OutputName           = OnboardImageAcquisitionTimeET
  Translation          = (*, *)
End_Group


Finding input element:

Product_Observational
  CaSSIS_Header
    DERIVED_HEADER_DATA
      OnboardImageAcquisitionTime

Testing dependencies:

Testing dependency number 1
  Specification:    att@Time_Base:ET

  Dependency type:  att
  Dependency name:  Time_Base
  Dependency value: ET

  Attribute name:   Time_Base  Attribute value:  UTC

Dependencies failed, checking next candidate.

Testing dependencies:

Testing dependency number 1
  Specification:    att@Time_Base:ET

  Dependency type:  att
  Dependency name:  Time_Base
  Dependency value: ET

  Attribute name:   Time_Base  Attribute value:  ET

Translating input value: 20161126.232452080

          ====================          

Translating output keyword: CoreBands

Translation group:
Group = CoreBands
  Auto                 = Null
  Debug                = Null
  InputPosition        = (Product_Observational, File_Area_Observational,
                          Array_2D_Image, Axis_Array)
  InputKeyDependencies = tag@axis_name:Band
  InputKey             = elements
  InputDefault         = 1
  OutputPosition       = (group, CoreCube)
  OutputName           = CoreBands
  Translation          = (*, *)
End_Group


Finding input element:

Product_Observational

Could not traverse input position, using default value: 1

          ====================          

Translating output keyword: CoreSamples

Translation group:
Group = CoreSamples
  Auto                 = Null
  Debug                = Null
  InputPosition        = (Product_Observational, File_Area_Observational,
                          Array_2D_Image, Axis_Array)
  InputKeyDependencies = tag@axis_name:Sample
  InputKey             = elements
  InputKeyAttribute    = Units
  InputDefault         = 2
  OutputPosition       = (group, CoreCube)
  OutputName           = CoreSamples
  Translation          = (*, *)
End_Group


Finding input element:

Product_Observational

Could not traverse input position, using default value: 2

          ====================          

Translating output keyword: CoreLines

Translation group:
Group = CoreLines
  Auto           = Null
  Debug          = Null
  InputPosition  = (Product_Observational, Bad_Parent)
  InputKey       = elements
  InputDefault   = 10
  OutputPosition = (group, CoreCube)
  OutputName     = CoreLines
  Translation    = (*, *)
End_Group


Finding input element:

Product_Observational

Could not traverse input position, using default value: 10

Group = instrument
  Version                        = UNK
  Host                           = TGO
  BandWidth                      = Broad
  SpacecraftName                 = TGO
  InstrumentId                   = CaSSIS
  OnboardImageAcquisitionTimeUTC = 2016-11-26T23:24:52.080
  OnboardImageAcquisitionTimeET  = 20161126.232452080
  Version                        = UNK
  Host                           = TGO
  BandWidth                      = Broad
  SpacecraftName                 = TGO
  InstrumentId                   = CaSSIS
  OnboardImageAcquisitionTimeUTC = 2016-11-26T23:24:52.080
  OnboardImageAcquisitionTimeET  = 20161126.232452080
End_Group

Group = CoreCube
  CoreBands   = 1
  CoreSamples = 2
  CoreLines   = 10
  CoreBands   = 1
  CoreSamples = 2
  CoreLines   = 10
End_Group
End

Testing SetLabel method

Testing error throws

**ERROR** Failed to translate output value for [InstrumentIfovWithUnits].
@@ -391,17 +780,13 @@ Testing error throws
**ERROR** Failed to translate output value for [InputKeyAttributeDoesNotExist].
**ERROR** Input element [INSTRUMENT_IFOV] does not have an attribute named [Bad_Input_Element_Attribute].

**ERROR** Failed to translate output value for [NoDependencyType].
**ERROR** Malformed dependency specification [type:Spacecraft].
**ERROR** Specification does not have two components separated by [@], the type of dependency and the name-value pair.

**ERROR** Failed to translate output value for [BadDependencyType].
**ERROR** Malformed dependency specification [bad@type:Spacecraft].
**ERROR** Dependency type specification [bad] is invalid. Valid types are [att] and [tag].
**ERROR** Dependency type specification [bad] is invalid. Valid types are [att], [tag] and [new].

**ERROR** Failed to translate output value for [NoDependencyValue].
**ERROR** Malformed dependency specification [bad@type].
**ERROR** Dependency type specification [bad] is invalid. Valid types are [att] and [tag].
**ERROR** Dependency type specification [bad] is invalid. Valid types are [att], [tag] and [new].

**ERROR** Failed to translate output value for [NotInTranslationTable].
**ERROR** Unable to retrieve translation group from translation table.
@@ -411,5 +796,5 @@ Testing error throws

**ERROR** Could not open label file [DoesNotExist.xml].

**ERROR** XML read/parse error in file [data/base/translations/pdsImage.trn] at line [1], column [1], message: error occurred while parsing element.
**ERROR** XML read/parse error in file [/usgs/cpkgs/isis3/data/base/translations/pdsImage.trn] at line [1], column [1], message: error occurred while parsing element.
+28 −8
Original line number Diff line number Diff line
@@ -5,20 +5,14 @@
#include "IException.h"
#include "IString.h"
#include "Preference.h"
#include "QRegularExpression"

using namespace Isis;
using namespace std;

void ReportError(QString err) {
  cout << err.replace(QRegularExpression("(\\/[\\w\\-\\. ]*)+\\/data"), "data") << endl;
}

int main(void) {
  Preference::Preferences(true);

  try {

    FileName fLabel("$base/testData/xmlTestLabel.xml");

    stringstream trnsStrm;
@@ -136,6 +130,11 @@ int main(void) {

    trnsStrm << "End" << endl;
    
    // Copy this buffer to use for additional tests
    std::stringstream trnsStrm2, trnsStrm3;
    trnsStrm2 << trnsStrm.rdbuf()->str();
    trnsStrm3 << trnsStrm.rdbuf()->str();

    stringstream badTrnsStrm;

    badTrnsStrm << "Group = NoInputPosition" << endl;
@@ -230,11 +229,32 @@ int main(void) {
    cout << "Translation of InstrumentIfovWithUnits: " <<
            transMgr.Translate("InstrumentIfovWithUnits") << endl << endl;

    cout << "Testing file-based constructor" << endl << endl;
    FileName XmltoPvlFile("$base/testData/XmlToPvlTestLabel.pvl");
    QString XmltoPvlFileString = XmltoPvlFile.toString(); 
    XmlToPvlTranslationManager transMgrFileConstructor(XmltoPvlFileString);

    cout << "Testing stream-only constructor" << endl << endl;
    XmlToPvlTranslationManager transMgrStreamConstructor(trnsStrm2);

    cout << "Testing constructor which uses an input label and translation file" << endl << endl;
    XmlToPvlTranslationManager transMgrFilesConstructor(fLabel, XmltoPvlFileString);

    cout << "Testing constructor which uses an input label and translation file" << endl << endl;
    XmlToPvlTranslationManager transMgrLabelStreamConstructor(fLabel, trnsStrm3);

    cout << "Testing Auto method" << endl << endl;
    Pvl outputLabel;
    transMgr.Auto(outputLabel);
    cout << endl << outputLabel << endl << endl;

    cout << "Testing Auto method with input and output labels" << endl << endl;
    transMgr.Auto(fLabel, outputLabel);
    cout << endl << outputLabel << endl << endl;

    cout << "Testing SetLabel method" << endl << endl;
    transMgr.SetLabel(fLabel);

    cout << "Testing error throws" << endl << endl;
    XmlToPvlTranslationManager badTransMgr(fLabel, badTrnsStrm);

@@ -352,7 +372,7 @@ int main(void) {
      XmlToPvlTranslationManager pvlTransFileManager(pvlFile, simpleTrans);
    }
    catch(IException &e) {
      ReportError(e.toString());
      e.print();
      cout << endl;
    }