'Parse a datatypes XML file located at root_dir/config (if processing the Galaxy distributed config) or contained within
an installed Tool Shed repository.  If deactivate is True, an installed Tool Shed repository that includes custom datatypes
is being deactivated or uninstalled, so appropriate loaded datatypes will be removed from the registry.  The value of
override will be False when a Tool Shed repository is being installed.  Since installation is occurring after the datatypes
registry has been initialized at server startup, its contents cannot be overridden by newly introduced conflicting data types.'

def load_datatypes(self, root_dir=None, config=None, deactivate=False, override=True):

    def __import_module(full_path, datatype_module, datatype_class_name):
        (open_file_obj, file_name, description) = imp.find_module(datatype_module, [full_path])
        imported_module = imp.load_module(datatype_class_name, open_file_obj, file_name, description)
        return imported_module
    if (root_dir and config):
        handling_proprietary_datatypes = False
        if (not isinstance(config, Element)):
            tree = galaxy.util.parse_xml(config)
            root = tree.getroot()
            if deactivate:
                self.log.debug(('Deactivating    datatypes    from    %s' % config))
            else:
                self.log.debug(('Loading    datatypes    from    %s' % config))
        else:
            root = config
        registration = root.find('registration')
        if (not self.converters_path):
            self.converters_path_attr = registration.get('converters_path', 'lib/galaxy/datatypes/converters')
            self.converters_path = os.path.join(root_dir, self.converters_path_attr)
            if (not os.path.isdir(self.converters_path)):
                raise ConfigurationError(('Directory    does    not    exist:    %s' % self.converters_path))
        if (not self.display_applications_path):
            self.display_path_attr = registration.get('display_path', 'display_applications')
            self.display_applications_path = os.path.join(root_dir, self.display_path_attr)
        proprietary_converter_path = registration.get('proprietary_converter_path', None)
        proprietary_display_path = registration.get('proprietary_display_path', None)
        if ((proprietary_converter_path is not None) or ((proprietary_display_path is not None) and (not handling_proprietary_datatypes))):
            handling_proprietary_datatypes = True
        for elem in registration.findall('datatype'):
            ok = True
            extension = self.get_extension(elem)
            dtype = elem.get('type', None)
            type_extension = elem.get('type_extension', None)
            mimetype = elem.get('mimetype', None)
            display_in_upload = galaxy.util.string_as_bool(elem.get('display_in_upload', False))
            make_subclass = galaxy.util.string_as_bool(elem.get('subclass', False))
            edam_format = elem.get('edam_format', None)
            if (edam_format and (not make_subclass)):
                self.log.warning('Cannot    specify    edam_format    without    setting    subclass    to    True,    skipping    datatype.')
                continue
            edam_data = elem.get('edam_data', None)
            if (edam_data and (not make_subclass)):
                self.log.warning('Cannot    specify    edam_data    without    setting    subclass    to    True,    skipping    datatype.')
                continue
            proprietary_path = elem.get('proprietary_path', None)
            proprietary_datatype_module = elem.get('proprietary_datatype_module', None)
            if ((proprietary_path is not None) or ((proprietary_datatype_module is not None) and (not handling_proprietary_datatypes))):
                handling_proprietary_datatypes = True
            if deactivate:
                for in_memory_elem in self.datatype_elems:
                    in_memory_extension = in_memory_elem.get('extension', None)
                    if (in_memory_extension == extension):
                        in_memory_dtype = elem.get('type', None)
                        in_memory_type_extension = elem.get('type_extension', None)
                        in_memory_mimetype = elem.get('mimetype', None)
                        in_memory_display_in_upload = galaxy.util.string_as_bool(elem.get('display_in_upload', False))
                        in_memory_make_subclass = galaxy.util.string_as_bool(elem.get('subclass', False))
                        if ((in_memory_dtype == dtype) and (in_memory_type_extension == type_extension) and (in_memory_mimetype == mimetype) and (in_memory_display_in_upload == display_in_upload) and (in_memory_make_subclass == make_subclass)):
                            self.datatype_elems.remove(in_memory_elem)
                if ((extension is not None) and (extension in self.datatypes_by_extension)):
                    del self.datatypes_by_extension[extension]
                    if (extension in self.upload_file_formats):
                        self.upload_file_formats.remove(extension)
                    self.log.debug(("Removed    datatype    with    extension    '%s'    from    the    registry." % extension))
            else:
                can_process_datatype = False
                if (extension is not None):
                    if ((dtype is not None) or (type_extension is not None)):
                        if (override or (extension not in self.datatypes_by_extension)):
                            can_process_datatype = True
                if can_process_datatype:
                    if (dtype is not None):
                        try:
                            fields = dtype.split(':')
                            datatype_module = fields[0]
                            datatype_class_name = fields[1]
                        except Exception as e:
                            self.log.exception('Error    parsing    datatype    definition    for    dtype    %s', str(dtype))
                            ok = False
                        if ok:
                            datatype_class = None
                            if (proprietary_path and proprietary_datatype_module and datatype_class_name):
                                try:
                                    imported_module = __import_module(proprietary_path, proprietary_datatype_module, datatype_class_name)
                                    if (imported_module not in self.imported_modules):
                                        self.imported_modules.append(imported_module)
                                    if hasattr(imported_module, datatype_class_name):
                                        datatype_class = getattr(imported_module, datatype_class_name)
                                except Exception as e:
                                    full_path = os.path.join(proprietary_path, proprietary_datatype_module)
                                    self.log.debug(('Exception    importing    proprietary    code    file    %s:    %s' % (str(full_path), str(e))))
                            if (datatype_class is None):
                                try:
                                    fields = datatype_module.split('.')[1:]
                                    module = __import__(datatype_module)
                                    for mod in fields:
                                        module = getattr(module, mod)
                                    datatype_class = getattr(module, datatype_class_name)
                                    self.log.debug(('Retrieved    datatype    module    %s:%s    from    the    datatype    registry.' % (str(datatype_module), datatype_class_name)))
                                except Exception as e:
                                    self.log.exception('Error    importing    datatype    module    %s', str(datatype_module))
                                    ok = False
                    elif (type_extension is not None):
                        try:
                            datatype_class = self.datatypes_by_extension[type_extension].__class__
                        except Exception as e:
                            self.log.exception('Error    determining    datatype_class    for    type_extension    %s', str(type_extension))
                            ok = False
                    if ok:
                        if (not deactivate):
                            if (extension in self.datatypes_by_extension):
                                self.log.debug(("Overriding    conflicting    datatype    with    extension    '%s',    using    datatype    from    %s." % (str(extension), str(config))))
                            if make_subclass:
                                datatype_class = type(datatype_class_name, (datatype_class,), {})
                                if edam_format:
                                    datatype_class.edam_format = edam_format
                                if edam_data:
                                    datatype_class.edam_data = edam_data
                            self.datatypes_by_extension[extension] = datatype_class()
                            if (mimetype is None):
                                mimetype = self.datatypes_by_extension[extension].get_mime()
                            self.mimetypes_by_extension[extension] = mimetype
                            if datatype_class.track_type:
                                self.available_tracks.append(extension)
                            if (display_in_upload and (extension not in self.upload_file_formats)):
                                self.upload_file_formats.append(extension)
                            self.datatypes_by_extension[extension].max_optional_metadata_filesize = elem.get('max_optional_metadata_filesize', None)
                            for converter in elem.findall('converter'):
                                converter_config = converter.get('file', None)
                                target_datatype = converter.get('target_datatype', None)
                                depends_on = converter.get('depends_on', None)
                                if ((depends_on is not None) and (target_datatype is not None)):
                                    if (extension not in self.converter_deps):
                                        self.converter_deps[extension] = {}
                                    self.converter_deps[extension][target_datatype] = depends_on.split(',')
                                if (converter_config and target_datatype):
                                    if proprietary_converter_path:
                                        self.proprietary_converters.append((converter_config, extension, target_datatype))
                                    else:
                                        self.converters.append((converter_config, extension, target_datatype))
                            for composite_file in elem.findall('composite_file'):
                                name = composite_file.get('name', None)
                                if (name is None):
                                    self.log.warning(('You    must    provide    a    name    for    your    composite_file    (%s).' % composite_file))
                                optional = composite_file.get('optional', False)
                                mimetype = composite_file.get('mimetype', None)
                                self.datatypes_by_extension[extension].add_composite_file(name, optional=optional, mimetype=mimetype)
                            for display_app in elem.findall('display'):
                                if proprietary_display_path:
                                    if (elem not in self.proprietary_display_app_containers):
                                        self.proprietary_display_app_containers.append(elem)
                                elif (elem not in self.display_app_containers):
                                    self.display_app_containers.append(elem)
                            self.datatype_elems.append(elem)
                elif (extension is not None):
                    if ((dtype is not None) or (type_extension is not None)):
                        if (extension in self.datatypes_by_extension):
                            if (not override):
                                self.log.debug(("Ignoring    conflicting    datatype    with    extension    '%s'    from    %s." % (extension, config)))
        self.load_datatype_sniffers(root, deactivate=deactivate, handling_proprietary_datatypes=handling_proprietary_datatypes, override=override)
        self.upload_file_formats.sort()
        self._load_build_sites(root)
    self.set_default_values()
    def append_to_sniff_order():
        for (ext, datatype) in self.datatypes_by_extension.items():
            included = False
            for atype in self.sniff_order:
                if isinstance(atype, datatype.__class__):
                    included = True
                    break
            if (not included):
                self.sniff_order.append(datatype)
    append_to_sniff_order()
