def main():

    parser = argparse.ArgumentParser()
    parser.add_argument("-l", "--library", help="External library to load.")
    parser.add_argument("-p", "--package", help="Package name to parse like: Modelica.SIunits",
                        default="Modelica.SIunits")
    args = parser.parse_args()

    omc = OMCSession()
    
    print "Loading Modelica library ..."
    success = omc.loadModel('Modelica')    
    if success:
        print "[OK]"
    else:
        print "[FAILED]"
        return
        
    if args.library:
        print "Loading External library {0} ...".format(args.library)
        cwd = os.getcwd()
        dir_name = os.path.dirname(args.library)
        os.chdir(dir_name)
        success = success and omc.loadFile(args.library)
        os.chdir(cwd)
        if success:
            print "[OK]"
        else:
            print "[FAILED]"

    if success:
        print "Getting all class names for package: {0}".format(args.package)
        modelica_classes = omc.getClassNames(args.package, recursive=True, qualified=True, sort=True)
        #print modelica_classes

        result = []
        for modelica_class in modelica_classes:
            info = {}
            info['name'] = modelica_class
            class_restriction = omc.getClassRestriction(modelica_class)
            info['class'] = class_restriction
            #info['text'] = omc.list(modelica_class)
            info['modifiers'] = {}
            print modelica_class
            modifiers = omc.getDerivedClassModifierNames(modelica_class)
            for modifier in modifiers:
                modifier_value = omc.getDerivedClassModifierValue(modelica_class, modifier)
                # ' = "value"' => 'value'
                modifier_value = modifier_value[3:].strip('"')
                info['modifiers'][modifier] = modifier_value

            getBaseClassModifiers(omc, modelica_class, info['modifiers'])

            result.append(info)
        
        output_filename = 'modelica_units.json'
        with open(output_filename, 'w') as f_p:
            json.dump(result, f_p)
        
        print 'File was generated: {0}'.format(output_filename)
Пример #2
0
class TreeExporter(object):
    def __init__(self, className):
        self.classNames = list()
        self.classNames.append(className)
        self.classDetails = list()

        self.logger = logging.getLogger('py_modelica_exporter.TreeExporter')
        self.logger.setLevel(logging.NOTSET)

        self.logger.info('Initializing TreeExporter({0})'.format(className))

        self.omc = OMCSession()

        # load all packages
        success = self.omc.loadModel('Modelica')
        # TODO: load all external packages

        self.parse_tree(className)

    def parse_tree(self, className):

        classNames = self.omc.getClassNames(className,
                                            recursive=True,
                                            sort=True)

        # filter and export only blocks and models
        for c_name in classNames:
            if (self.omc.isModel(c_name)) or (self.omc.isBlock(c_name)):
                class_details = dict()
                class_details['ComponentName'] = c_name
                class_details['Description'] = self.omc.getClassComment(c_name)
                self.classDetails.append(class_details)

    def json(self):
        json_result = dict()
        json_result['topLevelPackages'] = self.classNames
        json_result['classDetails'] = self.classDetails
        return json_result

    def xml(self):
        raise NotImplementedError

    def export_to_json(self, filename):
        json_result = self.json()

        with open(filename, 'w') as f_p:
            json.dump(json_result, f_p, indent=4)

        return json_result

    def export_to_xml(self, filename):
        raise NotImplementedError
class TreeExporter(object):

    def __init__(self, className):
        self.classNames = list()
        self.classNames.append(className)
        self.classDetails = list()

        self.logger = logging.getLogger('py_modelica_exporter.TreeExporter')
        self.logger.setLevel(logging.NOTSET)

        self.logger.info('Initializing TreeExporter({0})'.format(className))

        self.omc = OMCSession()

        # load all packages
        success = self.omc.loadModel('Modelica')
        # TODO: load all external packages

        self.parse_tree(className)

    def parse_tree(self, className):

        classNames = self.omc.getClassNames(className, recursive=True, sort=True)

        # filter and export only blocks and models
        for c_name in classNames:
            if (self.omc.isModel(c_name)) or (self.omc.isBlock(c_name)):
                class_details = dict()
                class_details['ComponentName'] = c_name
                class_details['Description'] = self.omc.getClassComment(c_name)
                self.classDetails.append(class_details)

    def json(self):
        json_result = dict()
        json_result['topLevelPackages'] = self.classNames
        json_result['classDetails'] = self.classDetails
        return json_result

    def xml(self):
        raise NotImplementedError

    def export_to_json(self, filename):
        json_result = self.json()

        with open(filename, 'w') as f_p:
            json.dump(json_result, f_p, indent=4)

        return json_result

    def export_to_xml(self, filename):
        raise NotImplementedError
Пример #4
0
class PackageExporter(object):
    """
    Class PackageExporter is an interface with the OpenModelicaCompiler to facilitate extraction of all classes
    contained within 'external_packages' (and the MSL)
    """
    def __init__(self, external_packages, load_msl=True):
        """
        Create an instance of the PackageExporter
        """
        self.external_package_paths = make_paths_safe_for_omc(
            external_packages)
        self.package_names = list()
        self.failed_load_package_names = list()
        self.class_details = list()

        self.logger = logging.getLogger('py_modelica_exporter.PackageExporter')
        self.logger.setLevel(logging.NOTSET)
        self.logger.info('Initializing PackageExporter({0})'.format(
            self.external_package_paths))

        self.omc = OMCSession()
        self.load_packages(self.external_package_paths, load_msl=load_msl)
        self.get_class_details(self.package_names)

    def parse_argument(self, external_packages):
        """
        This will update self.external_package_paths and self.package_names
        """
        for potential_path in external_packages:
            if os.path.exists(potential_path):
                self.external_package_paths.append(potential_path)

                if os.path.basename(
                        potential_path
                ) == 'package.mo':  # check if the file name is 'package.mo'
                    package_dir = os.path.dirname(
                        potential_path)  # get the path to the last directory
                    package_name = os.path.basename(
                        package_dir)  # get the name of the last directory
                    self.package_names.append(package_name)  # store that name
                else:
                    file_path, file_extension = os.path.splitext(
                        potential_path)
                    if file_extension == '.mo':  # make sure it is a '.mo' file
                        package_name = os.path.basename(
                            file_path)  # get the name of the file
                        self.package_names.append(
                            package_name)  # store that name
            # else:
            #     pass  # should log that this package path is invalid?

    def load_packages(self, external_package_paths, load_msl=True):
        """
        load all the external packages using OpenModelicaCompiler
        """

        if load_msl:
            if self.omc.loadModel('Modelica'):
                comment = self.omc.getClassComment('Modelica')

                import re

                modelica_version_pattern = '.*Version ([\d\.]*)'
                regex_modelica_version = re.findall(modelica_version_pattern,
                                                    comment)

                if regex_modelica_version[0]:
                    self.package_names.append('Modelica ' +
                                              regex_modelica_version[0])
                else:
                    self.package_names.append('Modelica')

        for package_path in external_package_paths:
            if os.path.isfile(package_path):  # make sure the file exists
                if os.path.basename(
                        package_path
                ) == 'package.mo':  # check if the file name is 'package.mo'
                    package_dir = os.path.dirname(
                        package_path)  # get the path to the last directory
                    package_name = os.path.basename(
                        package_dir
                    )  # get the name of the last directory (package_name)
                    if self.omc.loadFile(
                            package_path):  # try to load the package file
                        self.package_names.append(
                            package_name)  # log successful load
                        self.logger.info(
                            'Library loaded from : {0}'.format(package_path))
                    else:
                        self.failed_load_package_names.append(
                            "FAILED_" + package_name)  # log failure
                        self.logger.warning(
                            'Failed to load: {0}'.format(package_path))
                else:
                    file_path, file_extension = os.path.splitext(package_path)
                    if file_extension == '.mo':  # make sure it is a '.mo' file
                        package_name = os.path.basename(
                            file_path)  # get the name of the file
                        if self.omc.loadFile(
                                package_path):  # try to load the package file
                            self.package_names.append(
                                package_name)  # log successful load
                            self.logger.info(
                                'Library loaded from : {0}'.format(
                                    package_path))
                        else:
                            self.failed_load_package_names.append(
                                "FAILED_" + package_name)  # log failure
                            self.logger.warning(
                                'Failed to load: {0}'.format(package_path))
            else:
                file_path, file_extension = os.path.splitext(package_path)
                if file_extension == '.mo':  # make sure it is a '.mo' file
                    package_name = os.path.basename(
                        file_path)  # get the name of the file
                    if package_name == 'package':
                        package_name = os.path.basename(
                            os.path.dirname(file_path))

                    self.failed_load_package_names.append(package_name)
                    self.logger.warning(
                        'Failed to load: {0}'.format(package_path))

    def get_class_details(self, package_names):
        """
        Get the class details and write out a json file
        """

        for package_name in package_names:
            get_comments = False  # self.omc.getClassNames randomly (?) takes a long time to execute

            if 'Modelica' in package_name:
                class_names = self.omc.getClassNames('Modelica',
                                                     recursive=True,
                                                     sort=True)
                # get_comments = True

                # blacklist = ['.Utilities.',
                #              '.UsersGuide.',
                #              '.Examples.',
                #              '.UnitConversions.',
                #              '.Media.']

                # for c_name in class_names:
                #     # skip_it = False
                #     # for bad_name in blacklist:
                #     #     if bad_name in c_name:
                #     #         skip_it = True
                #     #         self.logger.info(c_name + " is black-listed (not a model or block)")
                #     #         break
                #     # if skip_it:
                #     #     continue
                #
                #     class_details = dict()
                #     class_details['ComponentName'] = c_name
                #     class_details['Description'] = ""  # self.omc.getClassComment(c_name)
                #     self.class_details.append(class_details)

            else:
                class_names = self.omc.getClassNames(package_name,
                                                     recursive=True,
                                                     sort=True)
                # get_comments = True

            for c_name in class_names:

                class_details = dict()
                class_details['ComponentName'] = c_name
                if get_comments:
                    class_details['Description'] = self.omc.getClassComment(
                        c_name)
                else:
                    class_details['Description'] = "None available"

                self.class_details.append(class_details)

                # model_type = self.omc.getClassRestriction(c_name)
                # if model_type in ['model', 'block']:
                # # if (self.omc.isModel(c_name)) or (self.omc.isBlock(c_name)):  # only blocks and models are exported
                #     class_details = dict()
                #     class_details['ComponentName'] = c_name
                #     class_details['Description'] = self.omc.getClassComment(c_name)
                #     self.class_details.append(class_details)

    def json(self):
        """
        Generate a dictionary from the Packages
        """
        json_result = dict()
        json_result[
            'topLevelPackages'] = self.package_names + self.failed_load_package_names
        json_result['classDetails'] = self.class_details
        return json_result

    def export_to_json(self, filename):
        """
        Write a json file of the Packages
        """
        json_result = self.json()

        with open(filename, 'w') as f_p:
            json.dump(json_result, f_p, indent=4)

        return json_result
Пример #5
0
class TreeExporter(object):
    """
    Class TreeExporter is an interface with the OpenModelicaCompiler to facilitate extraction of all contained classes
    """
    def __init__(self, class_name):
        """
        creates an instance of TreeExporter
        """
        self.class_names = list()
        self.class_names.append(class_name)
        self.class_details = list()

        self.logger = logging.getLogger('py_modelica_exporter.TreeExporter')
        self.logger.setLevel(logging.NOTSET)

        self.logger.info('Initializing TreeExporter({0})'.format(class_name))

        self.omc = OMCSession()

        # load all packages
        success = self.omc.loadModel('Modelica')

        self.parse_tree(class_name)

    def parse_tree(self, class_name):
        """
        gets all classes from within 'class_name'
        """

        class_names = self.omc.getClassNames(class_name,
                                             recursive=True,
                                             sort=True)

        # filter and export only blocks and models
        for c_name in class_names:
            # if (self.omc.isModel(c_name)) or (self.omc.isBlock(c_name)):
            class_details = dict()
            class_details['ComponentName'] = c_name
            class_details[
                'Description'] = "None available"  # self.omc.getClassComment(c_name)
            self.class_details.append(class_details)

    def json(self):
        """
        Creates a dictionary from of all the classes contained in the Tree
        """
        json_result = dict()
        json_result['topLevelPackages'] = self.class_names
        json_result['classDetails'] = self.class_details
        return json_result

    def xml(self):
        raise NotImplementedError

    def export_to_json(self, filename):
        """
        Write out a json representation of the Tree
        """
        json_result = self.json()

        with open(filename, 'w') as f_p:
            json.dump(json_result, f_p, indent=4)

        return json_result

    def export_to_xml(self, filename):
        raise NotImplementedError
class PackageExporter(object):

    def __init__(self, external_packages, load_MSL=True):

        self.externalPackagePaths = make_paths_safe_for_omc(external_packages)
        self.packageNames = list()
        self.failedLoadPackageNames = list()
        self.classDetails = list()

        self.logger = logging.getLogger('py_modelica_exporter.PackageExporter')
        self.logger.setLevel(logging.NOTSET)
        self.logger.info('Initializing PackageExporter({0})'.format(self.externalPackagePaths))

        self.omc = OMCSession()
        self.loadPackages(self.externalPackagePaths, load_MSL=load_MSL)
        self.getClassDetails(self.packageNames)

    def parseArgument(self, externalPackages):
        # this will update self.externalPackagePaths and self.externalPackageNames

        for potentialPath in externalPackages:
            if os.path.exists(potentialPath):
                self.externalPackagePaths.append(potentialPath)

                if os.path.basename(potentialPath) == 'package.mo':     # check if the file name is 'package.mo'
                    packageDir = os.path.dirname(potentialPath)         # get the path to the last directory
                    packageName = os.path.basename(packageDir)          # get the name of the last directory
                    self.packageNames.append(packageName)       # store that name
                else:
                    file_path, file_extension = os.path.splitext(potentialPath)
                    if file_extension == '.mo':                         # make sure it is a '.mo' file
                        packageName = os.path.basename(file_path)       # get the name of the file
                        self.packageNames.append(packageName)   # store that name
            else:
                pass  # should log that this package path is invalid?

    def loadPackages(self, external_package_paths, load_MSL=True):

        if load_MSL:
            if self.omc.loadModel('Modelica') == True:
                comment = self.omc.getClassComment('Modelica')

                import re
                modelica_version_pattern = '.*Version ([\d\.]*)'
                regex_modelica_version = re.findall(modelica_version_pattern, comment)

                if regex_modelica_version[0]:
                    self.packageNames.append('Modelica ' + regex_modelica_version[0])
                else:
                    self.packageNames.append('Modelica')

        for package_path in external_package_paths:
            if os.path.isfile(package_path) == True:                # make sure the file exists
                if os.path.basename(package_path) == 'package.mo':  # check if the file name is 'package.mo'
                    package_dir = os.path.dirname(package_path)     # get the path to the last directory
                    package_name = os.path.basename(package_dir)    # get the name of the last directory (package_name)
                    if self.omc.loadFile(package_path) == True:     # try to load the package file
                        self.packageNames.append(package_name)  # log successful load
                        self.logger.info('Library loaded from : {0}'.format(package_path))
                    else:
                        self.failedLoadPackageNames.append("FAILED_" + package_name)    # log failure
                        self.logger.warning('Failed to load: {0}'.format(package_path))
                else:
                    file_path, file_extension = os.path.splitext(package_path)
                    if file_extension == '.mo':                             # make sure it is a '.mo' file
                        package_name = os.path.basename(file_path)          # get the name of the file
                        if self.omc.loadFile(package_path) == True:         # try to load the package file
                            self.packageNames.append(package_name)  # log successful load
                            self.logger.info('Library loaded from : {0}'.format(package_path))
                        else:
                            self.failedLoadPackageNames.append("FAILED_" + package_name)    # log failure
                            self.logger.warning('Failed to load: {0}'.format(package_path))
            else:
                file_path, file_extension = os.path.splitext(package_path)
                if file_extension == '.mo':                            # make sure it is a '.mo' file
                    package_name = os.path.basename(file_path)          # get the name of the file
                    if package_name == 'package':
                        package_name = os.path.basename(os.path.dirname(file_path))

                    self.failedLoadPackageNames.append(package_name)
                    self.logger.warning('Failed to load: {0}'.format(package_path))

    def getClassDetails(self, packageNames):

        for packageName in packageNames:
            if 'Modelica' in packageName:
                classNames = self.omc.getClassNames('Modelica', recursive=True, sort=True)
            else:
                classNames = self.omc.getClassNames(packageName, recursive=True, sort=True)

            for c_name in classNames:
                if (self.omc.isModel(c_name)) or (self.omc.isBlock(c_name)): # only blocks and models are exported
                    class_details = dict()
                    class_details['ComponentName'] = c_name
                    class_details['Description'] = self.omc.getClassComment(c_name)
                    self.classDetails.append(class_details)

    def json(self):
        json_result = dict()
        json_result['topLevelPackages'] = self.packageNames + self.failedLoadPackageNames
        json_result['classDetails'] = self.classDetails
        return json_result

    def exportToJson(self, filename):
        json_result = self.json()

        with open(filename, 'w') as f_p:
            json.dump(json_result, f_p, indent=4)

        return json_result
Пример #7
0
class PackageExporter(object):
    """
    Class PackageExporter is an interface with the OpenModelicaCompiler to facilitate extraction of all classes
    contained within 'external_packages' (and the MSL)
    """

    def __init__(self, external_packages, load_msl=True):
        """
        Create an instance of the PackageExporter
        """
        self.external_package_paths = make_paths_safe_for_omc(external_packages)
        self.package_names = list()
        self.failed_load_package_names = list()
        self.class_details = list()

        self.logger = logging.getLogger('py_modelica_exporter.PackageExporter')
        self.logger.setLevel(logging.NOTSET)
        self.logger.info('Initializing PackageExporter({0})'.format(self.external_package_paths))

        self.omc = OMCSession()
        self.load_packages(self.external_package_paths, load_msl=load_msl)
        self.get_class_details(self.package_names)

    def parse_argument(self, external_packages):
        """
        This will update self.external_package_paths and self.package_names
        """
        for potential_path in external_packages:
            if os.path.exists(potential_path):
                self.external_package_paths.append(potential_path)

                if os.path.basename(potential_path) == 'package.mo':     # check if the file name is 'package.mo'
                    package_dir = os.path.dirname(potential_path)         # get the path to the last directory
                    package_name = os.path.basename(package_dir)          # get the name of the last directory
                    self.package_names.append(package_name)       # store that name
                else:
                    file_path, file_extension = os.path.splitext(potential_path)
                    if file_extension == '.mo':                         # make sure it is a '.mo' file
                        package_name = os.path.basename(file_path)       # get the name of the file
                        self.package_names.append(package_name)   # store that name
            # else:
            #     pass  # should log that this package path is invalid?

    def load_packages(self, external_package_paths, load_msl=True):
        """
        load all the external packages using OpenModelicaCompiler
        """

        if load_msl:
            if self.omc.loadModel('Modelica'):
                comment = self.omc.getClassComment('Modelica')

                import re

                modelica_version_pattern = '.*Version ([\d\.]*)'
                regex_modelica_version = re.findall(modelica_version_pattern, comment)

                if regex_modelica_version[0]:
                    self.package_names.append('Modelica ' + regex_modelica_version[0])
                else:
                    self.package_names.append('Modelica')

        for package_path in external_package_paths:
            if os.path.isfile(package_path):                # make sure the file exists
                if os.path.basename(package_path) == 'package.mo':  # check if the file name is 'package.mo'
                    package_dir = os.path.dirname(package_path)     # get the path to the last directory
                    package_name = os.path.basename(package_dir)    # get the name of the last directory (package_name)
                    if self.omc.loadFile(package_path):     # try to load the package file
                        self.package_names.append(package_name)  # log successful load
                        self.logger.info('Library loaded from : {0}'.format(package_path))
                    else:
                        self.failed_load_package_names.append("FAILED_" + package_name)    # log failure
                        self.logger.warning('Failed to load: {0}'.format(package_path))
                else:
                    file_path, file_extension = os.path.splitext(package_path)
                    if file_extension == '.mo':                             # make sure it is a '.mo' file
                        package_name = os.path.basename(file_path)          # get the name of the file
                        if self.omc.loadFile(package_path):         # try to load the package file
                            self.package_names.append(package_name)  # log successful load
                            self.logger.info('Library loaded from : {0}'.format(package_path))
                        else:
                            self.failed_load_package_names.append("FAILED_" + package_name)    # log failure
                            self.logger.warning('Failed to load: {0}'.format(package_path))
            else:
                file_path, file_extension = os.path.splitext(package_path)
                if file_extension == '.mo':                            # make sure it is a '.mo' file
                    package_name = os.path.basename(file_path)          # get the name of the file
                    if package_name == 'package':
                        package_name = os.path.basename(os.path.dirname(file_path))

                    self.failed_load_package_names.append(package_name)
                    self.logger.warning('Failed to load: {0}'.format(package_path))

    def get_class_details(self, package_names):
        """
        Get the class details and write out a json file
        """

        for package_name in package_names:
            get_comments = False  # self.omc.getClassNames randomly (?) takes a long time to execute

            if 'Modelica' in package_name:
                class_names = self.omc.getClassNames('Modelica', recursive=True, sort=True)
                # get_comments = True

                # blacklist = ['.Utilities.',
                #              '.UsersGuide.',
                #              '.Examples.',
                #              '.UnitConversions.',
                #              '.Media.']

                # for c_name in class_names:
                #     # skip_it = False
                #     # for bad_name in blacklist:
                #     #     if bad_name in c_name:
                #     #         skip_it = True
                #     #         self.logger.info(c_name + " is black-listed (not a model or block)")
                #     #         break
                #     # if skip_it:
                #     #     continue
                #
                #     class_details = dict()
                #     class_details['ComponentName'] = c_name
                #     class_details['Description'] = ""  # self.omc.getClassComment(c_name)
                #     self.class_details.append(class_details)

            else:
                class_names = self.omc.getClassNames(package_name, recursive=True, sort=True)
                # get_comments = True

            for c_name in class_names:

                class_details = dict()
                class_details['ComponentName'] = c_name
                if get_comments:
                    class_details['Description'] = self.omc.getClassComment(c_name)
                else:
                    class_details['Description'] = "None available"

                self.class_details.append(class_details)

                # model_type = self.omc.getClassRestriction(c_name)
                # if model_type in ['model', 'block']:
                # # if (self.omc.isModel(c_name)) or (self.omc.isBlock(c_name)):  # only blocks and models are exported
                #     class_details = dict()
                #     class_details['ComponentName'] = c_name
                #     class_details['Description'] = self.omc.getClassComment(c_name)
                #     self.class_details.append(class_details)


    def json(self):
        """
        Generate a dictionary from the Packages
        """
        json_result = dict()
        json_result['topLevelPackages'] = self.package_names + self.failed_load_package_names
        json_result['classDetails'] = self.class_details
        return json_result

    def export_to_json(self, filename):
        """
        Write a json file of the Packages
        """
        json_result = self.json()

        with open(filename, 'w') as f_p:
            json.dump(json_result, f_p, indent=4)

        return json_result
Пример #8
0
class TreeExporter(object):
    """
    Class TreeExporter is an interface with the OpenModelicaCompiler to facilitate extraction of all contained classes
    """

    def __init__(self, class_name):
        """
        creates an instance of TreeExporter
        """
        self.class_names = list()
        self.class_names.append(class_name)
        self.class_details = list()

        self.logger = logging.getLogger('py_modelica_exporter.TreeExporter')
        self.logger.setLevel(logging.NOTSET)

        self.logger.info('Initializing TreeExporter({0})'.format(class_name))

        self.omc = OMCSession()

        # load all packages
        success = self.omc.loadModel('Modelica')

        self.parse_tree(class_name)

    def parse_tree(self, class_name):
        """
        gets all classes from within 'class_name'
        """

        class_names = self.omc.getClassNames(class_name, recursive=True, sort=True)

        # filter and export only blocks and models
        for c_name in class_names:
            # if (self.omc.isModel(c_name)) or (self.omc.isBlock(c_name)):
            class_details = dict()
            class_details['ComponentName'] = c_name
            class_details['Description'] = "None available"  # self.omc.getClassComment(c_name)
            self.class_details.append(class_details)

    def json(self):
        """
        Creates a dictionary from of all the classes contained in the Tree
        """
        json_result = dict()
        json_result['topLevelPackages'] = self.class_names
        json_result['classDetails'] = self.class_details
        return json_result

    def xml(self):
        raise NotImplementedError

    def export_to_json(self, filename):
        """
        Write out a json representation of the Tree
        """
        json_result = self.json()

        with open(filename, 'w') as f_p:
            json.dump(json_result, f_p, indent=4)

        return json_result

    def export_to_xml(self, filename):
        raise NotImplementedError
Пример #9
0
class PackageExporter(object):
    def __init__(self, external_packages, load_MSL=True):

        self.externalPackagePaths = make_paths_safe_for_omc(external_packages)
        self.packageNames = list()
        self.failedLoadPackageNames = list()
        self.classDetails = list()

        self.logger = logging.getLogger('py_modelica_exporter.PackageExporter')
        self.logger.setLevel(logging.NOTSET)
        self.logger.info('Initializing PackageExporter({0})'.format(
            self.externalPackagePaths))

        self.omc = OMCSession()
        self.loadPackages(self.externalPackagePaths, load_MSL=load_MSL)
        self.getClassDetails(self.packageNames)

    def parseArgument(self, externalPackages):
        # this will update self.externalPackagePaths and self.externalPackageNames

        for potentialPath in externalPackages:
            if os.path.exists(potentialPath):
                self.externalPackagePaths.append(potentialPath)

                if os.path.basename(
                        potentialPath
                ) == 'package.mo':  # check if the file name is 'package.mo'
                    packageDir = os.path.dirname(
                        potentialPath)  # get the path to the last directory
                    packageName = os.path.basename(
                        packageDir)  # get the name of the last directory
                    self.packageNames.append(packageName)  # store that name
                else:
                    file_path, file_extension = os.path.splitext(potentialPath)
                    if file_extension == '.mo':  # make sure it is a '.mo' file
                        packageName = os.path.basename(
                            file_path)  # get the name of the file
                        self.packageNames.append(
                            packageName)  # store that name
            else:
                pass  # should log that this package path is invalid?

    def loadPackages(self, external_package_paths, load_MSL=True):

        if load_MSL:
            if self.omc.loadModel('Modelica') == True:
                comment = self.omc.getClassComment('Modelica')

                import re

                modelica_version_pattern = '.*Version ([\d\.]*)'
                regex_modelica_version = re.findall(modelica_version_pattern,
                                                    comment)

                if regex_modelica_version[0]:
                    self.packageNames.append('Modelica ' +
                                             regex_modelica_version[0])
                else:
                    self.packageNames.append('Modelica')

        for package_path in external_package_paths:
            if os.path.isfile(
                    package_path) == True:  # make sure the file exists
                if os.path.basename(
                        package_path
                ) == 'package.mo':  # check if the file name is 'package.mo'
                    package_dir = os.path.dirname(
                        package_path)  # get the path to the last directory
                    package_name = os.path.basename(
                        package_dir
                    )  # get the name of the last directory (package_name)
                    if self.omc.loadFile(
                            package_path
                    ) == True:  # try to load the package file
                        self.packageNames.append(
                            package_name)  # log successful load
                        self.logger.info(
                            'Library loaded from : {0}'.format(package_path))
                    else:
                        self.failedLoadPackageNames.append(
                            "FAILED_" + package_name)  # log failure
                        self.logger.warning(
                            'Failed to load: {0}'.format(package_path))
                else:
                    file_path, file_extension = os.path.splitext(package_path)
                    if file_extension == '.mo':  # make sure it is a '.mo' file
                        package_name = os.path.basename(
                            file_path)  # get the name of the file
                        if self.omc.loadFile(
                                package_path
                        ) == True:  # try to load the package file
                            self.packageNames.append(
                                package_name)  # log successful load
                            self.logger.info(
                                'Library loaded from : {0}'.format(
                                    package_path))
                        else:
                            self.failedLoadPackageNames.append(
                                "FAILED_" + package_name)  # log failure
                            self.logger.warning(
                                'Failed to load: {0}'.format(package_path))
            else:
                file_path, file_extension = os.path.splitext(package_path)
                if file_extension == '.mo':  # make sure it is a '.mo' file
                    package_name = os.path.basename(
                        file_path)  # get the name of the file
                    if package_name == 'package':
                        package_name = os.path.basename(
                            os.path.dirname(file_path))

                    self.failedLoadPackageNames.append(package_name)
                    self.logger.warning(
                        'Failed to load: {0}'.format(package_path))

    def getClassDetails(self, packageNames):

        for packageName in packageNames:
            if 'Modelica' in packageName:
                classNames = self.omc.getClassNames('Modelica',
                                                    recursive=True,
                                                    sort=True)
            else:
                classNames = self.omc.getClassNames(packageName,
                                                    recursive=True,
                                                    sort=True)

            for c_name in classNames:
                if (self.omc.isModel(c_name)) or (self.omc.isBlock(
                        c_name)):  # only blocks and models are exported
                    class_details = dict()
                    class_details['ComponentName'] = c_name
                    class_details['Description'] = self.omc.getClassComment(
                        c_name)
                    self.classDetails.append(class_details)

    def json(self):
        json_result = dict()
        json_result[
            'topLevelPackages'] = self.packageNames + self.failedLoadPackageNames
        json_result['classDetails'] = self.classDetails
        return json_result

    def exportToJson(self, filename):
        json_result = self.json()

        with open(filename, 'w') as f_p:
            json.dump(json_result, f_p, indent=4)

        return json_result