コード例 #1
0
class AdhocAction():

    sort_order_map = None
    common = Common()

    def removeRenameFieldInJRXMLFile(self, filename, fieldname, newfieldname,
                                     log):
        log.debug('Preparing to remove field(s) from JRXML file: ' +
                  filename[filename.rfind(Common.REPO_PATH_SEPARATOR) + 1:])
        with open(filename, 'r', encoding='utf-8') as h:
            report_xml = h.read()
        report_tuple = self.common.removeDeclarationNode(xml_string=report_xml)
        report_xml = report_tuple[1]
        parser = etree.XMLParser(strip_cdata=False)
        # remove queryString node that contains an extra XML declaration to avoid syntax error
        try:
            begin_index = report_xml.index('<?xml', 2)
        except ValueError:
            log.debug('Report does not contain a domain query.  Skipping...')
            begin_index = -1
        if begin_index > 0:
            end_index = report_xml.find(']]>', begin_index)
            report_xml_outer = report_xml[0:begin_index] + report_xml[
                end_index:len(report_xml)]
            report_xml_inner = report_xml[begin_index:end_index]
            report_root = etree.fromstring(report_xml_outer, parser)
            self.removeRenameFieldInJRXML(root=report_root,
                                          fieldname=fieldname,
                                          newfieldname=newfieldname,
                                          log=log)
            # remove the <?xml ?> declaration from the beginning because lxml fromstring() can't handle the encoding
            query_tag_index = report_xml_inner.find('<' + Common.QUERY)
            report_xml_inner = report_xml_inner[query_tag_index:]
            query_root = etree.fromstring(report_xml_inner)
            self.removeRenameQueryFieldInAdhocQuery(root=query_root,
                                                    fieldname=fieldname,
                                                    newfieldname=newfieldname,
                                                    log=log)
            # re-insert domain query back into topic
            query_bytea = etree.tostring(query_root,
                                         pretty_print=True,
                                         encoding='UTF-8')
            query_str = "".join(map(chr, query_bytea))
            self.reinsertQueryIntoMainBody(root=report_root,
                                           query_str=query_str)
        else:
            report_root = etree.fromstring(report_xml, parser)
            self.removeRenameFieldInJRXML(root=report_root,
                                          fieldname=fieldname,
                                          newfieldname=newfieldname,
                                          log=log)
        report_bytea = etree.tostring(report_root,
                                      pretty_print=True,
                                      encoding='UTF-8')
        report_xml = "".join(map(chr, report_bytea))
        # re-insert original XML declaration
        report_xml = report_tuple[0] + report_xml
        with open(filename, 'w', encoding='utf-8') as h:
            h.write(report_xml)

    def removeRenameFieldInJRXML(self, root, fieldname, newfieldname, log):
        semantic_tree_sort_order = None
        semantic_tree_sort_order_set = False
        semantic_tree_sort_order_deleted = False
        # if field is a parameter
        for param in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + Common.PARAMETER,
                                namespaces=Common.JRXML_NAMESPACE):
            nameValue = param.get(Common.NAME)
            if nameValue.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming parameter ' + nameValue + ' to ' +
                              nameValue.replace(fieldname, newfieldname))
                    param.attrib[Common.NAME] = nameValue.replace(
                        fieldname, newfieldname)
                else:
                    log.debug('removing parameter: ' + nameValue)
                    param.getparent().remove(param)
        # remove or rename field
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + Common.FIELD,
                                namespaces=Common.JRXML_NAMESPACE):
            nameValue = field.get(Common.NAME)
            if semantic_tree_sort_order_set == False and semantic_tree_sort_order_deleted == False:
                for child in field:
                    if child.get(Common.NAME) == Common.SORT_ORDER:
                        if newfieldname is not None and newfieldname != '_' and child.text is not None and child.text.find(
                                fieldname) >= 0:
                            child.text = etree.CDATA(
                                child.text.replace(fieldname, newfieldname))
                            semantic_tree_sort_order_set = True
                        else:
                            semantic_tree_sort_order = self.fixSortOrder(
                                fieldname=fieldname,
                                semantic_tree_sort_order=child.text)
                    # Fix any other property values where the fieldname appears
                    elif newfieldname is not None and newfieldname != '_' and child.get(
                            Common.VALUE) is not None and child.get(
                                Common.VALUE).find(fieldname) >= 0:
                        childValue = child.get(Common.VALUE)
                        log.debug('changing value for property ' +
                                  child.get(Common.NAME) + ' from ' +
                                  childValue + ' to ' +
                                  childValue.replace(fieldname, newfieldname))
                        child.attrib[Common.VALUE] = childValue.replace(
                            fieldname, newfieldname)
            if nameValue.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming field ' + nameValue + ' to ' +
                              nameValue.replace(fieldname, newfieldname))
                    field.attrib[Common.NAME] = nameValue.replace(
                        fieldname, newfieldname)
                else:
                    log.debug('removing field: ' + nameValue)
                    field.getparent().remove(field)
                    semantic_tree_sort_order_deleted = True
            else:
                for child in field:
                    if (child.get(Common.NAME) == Common.SORT_ORDER):
                        if semantic_tree_sort_order_set == False:
                            if (child.get(Common.VALUE) != None):
                                del child.attrib[Common.VALUE]
                            if semantic_tree_sort_order != None:
                                child.text = etree.CDATA(
                                    semantic_tree_sort_order)
                                semantic_tree_sort_order_set = True
                        elif newfieldname is None or newfieldname == '_':
                            field_key = field.get(Common.NAME)
                            if field_key.find('.') >= 0:
                                field_key = field_key[field_key.rfind('.') +
                                                      1:]
                            child.attrib[Common.VALUE] = self.sort_order_map[
                                '"' + field_key + '"']
            # Fix any other property values where the fieldname appears
            if newfieldname is not None and newfieldname != '_':
                for child in field:
                    if (child.get(Common.NAME) !=
                            Common.SORT_ORDER) and child.get(
                                Common.VALUE) is not None and child.get(
                                    Common.VALUE).find(fieldname) >= 0:
                        childValue = child.get(Common.VALUE)
                        log.debug('changing value for property ' +
                                  child.get(Common.NAME) + ' from ' +
                                  childValue + ' to ' +
                                  childValue.replace(fieldname, newfieldname))
                        child.attrib[Common.VALUE] = childValue.replace(
                            fieldname, newfieldname)

    def fixSortOrder(self, fieldname, semantic_tree_sort_order):
        if semantic_tree_sort_order != None:
            # Strip the curly braces and convert to a map
            semantic_tree_sort_order = semantic_tree_sort_order[
                semantic_tree_sort_order.find('{') +
                1:semantic_tree_sort_order.find('}')]
            self.sort_order_map = dict(
                item.split(':')
                for item in semantic_tree_sort_order.split(','))
            if '"' + fieldname + '"' in self.sort_order_map.keys():
                del self.sort_order_map['"' + fieldname + '"']
            self.fixSortingValues()
            semantic_tree_sort_order = ','.join(
                '%s:%d' % (k, int(v)) for k, v in self.sort_order_map.items())
            return '{' + semantic_tree_sort_order + '}'
        else:
            return None

    def fixSortingValues(self):
        if self.sort_order_map != None:
            smallest_value = 99999
            for value in self.sort_order_map.values():
                if int(value) < smallest_value:
                    smallest_value = int(value)
            value_diff = smallest_value - 1
            for key in self.sort_order_map.keys():
                self.sort_order_map[key] = str(
                    int(self.sort_order_map[key]) - value_diff)

    def removeRenameQueryFieldInAdhocQuery(self, root, fieldname, newfieldname,
                                           log):
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + 'n:' +
                                Common.QUERY_FIELD,
                                namespaces=Common.DOMAIN_QUERY_NAMESPACE):
            idValue = field.get(Common.ID)
            if idValue.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming field ' + idValue + ' to ' +
                              idValue.replace(fieldname, newfieldname))
                    field.attrib[Common.ID] = idValue.replace(
                        fieldname, newfieldname)
                else:
                    log.debug('removing field: ' + idValue)
                    field.getparent().remove(field)

    def reinsertQueryIntoMainBody(self, root, query_str):
        query_str = '<?xml version="1.0" encoding="UTF-8"?>\n' + query_str
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.QUERY_STRING,
                                namespaces=Common.JRXML_NAMESPACE):
            field.text = etree.CDATA(query_str)
        return query_str

    def removeRenameFieldInStateFile(self, filename, fieldname, newfieldname,
                                     log):
        log.debug('Preparing to remove field(s) from state file: ' +
                  filename[filename.rfind(Common.REPO_PATH_SEPARATOR) + 1:])
        with open(filename, 'r', encoding='utf-8') as h:
            state_xml = h.read()
        state_tuple = self.common.removeDeclarationNode(xml_string=state_xml)
        state_root = etree.fromstring(state_tuple[1])
        self.removeRenameFieldInState(root=state_root,
                                      fieldname=fieldname,
                                      newfieldname=newfieldname,
                                      log=log)
        state_bytea = etree.tostring(state_root,
                                     pretty_print=True,
                                     encoding='UTF-8')
        state_xml = "".join(map(chr, state_bytea))
        # re-insert original XML declaration
        state_xml = state_tuple[0] + state_xml
        if state_xml.endswith('\n'):
            state_xml = state_xml[0:len(state_xml) - 1]
        with open(filename, 'w', encoding='utf-8') as h:
            h.write(state_xml)

    def removeRenameFieldInState(self, root, fieldname, newfieldname, log):
        # if the field is a measure
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + Common.MEASURE):
            fieldnameValue = field.get(Common.FIELD_NAME)
            nameValue = field.get(Common.NAME)
            if fieldnameValue != None and fieldnameValue.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming measure from ' + fieldnameValue +
                              ' to ' +
                              fieldnameValue.replace(fieldname, newfieldname))
                    field.attrib[Common.FIELD_NAME] = fieldnameValue.replace(
                        fieldname, newfieldname)
                    if nameValue.find(fieldname) >= 0:
                        log.debug('renaming measure name attribute from ' +
                                  nameValue + ' to ' +
                                  nameValue.replace(fieldname, newfieldname))
                        field.attrib[Common.NAME] = nameValue.replace(
                            fieldname, newfieldname)
                    # check and rename the labelOverride property if necessary
                    labelOverride = field.get(Common.LABEL_OVERRIDE)
                    if labelOverride is not None and labelOverride.find(
                            fieldname) >= 0:
                        log.debug(
                            'changing labelOverride property from ' +
                            labelOverride + ' to ' +
                            labelOverride.replace(fieldname, newfieldname))
                        field.attrib[
                            Common.LABEL_OVERRIDE] = labelOverride.replace(
                                fieldname, newfieldname)
                else:
                    log.debug('removing measure: ' + fieldnameValue)
                    field.getparent().remove(field)
        # if the field is a dimension
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.QUERY_DIMENSION):
            fieldnameValue = field.get(Common.FIELD_NAME)
            nameValue = field.get(Common.NAME)
            if fieldnameValue != None and fieldnameValue.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming dimension from ' + fieldnameValue +
                              ' to ' +
                              fieldnameValue.replace(fieldname, newfieldname))
                    field.attrib[Common.FIELD_NAME] = fieldnameValue.replace(
                        fieldname, newfieldname)
                    if nameValue.find(fieldname) >= 0:
                        log.debug('renaming measure name attribute from ' +
                                  nameValue + ' to ' +
                                  nameValue.replace(fieldname, newfieldname))
                        field.attrib[Common.NAME] = nameValue.replace(
                            fieldname, newfieldname)
                else:
                    log.debug('removing dimension: ' + fieldnameValue)
                    field.getparent().remove(field)
        # if the field is a field
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + Common.FIELD,
                                namespaces=Common.DOMAIN_QUERY_NAMESPACE):
            idValue = field.get(Common.ID)
            if idValue != None and idValue.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming field ' + idValue + ' to ' +
                              idValue.replace(fieldname, newfieldname))
                    field.attrib[Common.ID] = idValue.replace(
                        fieldname, newfieldname)
                else:
                    log.debug('removing field: ' + idValue)
                    field.getparent().remove(field)
        # if the field is used in a parameter
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.EXPRESSION_STRING):
            if field.text.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    textValue = field.text
                    log.debug('changing expressionString ' + textValue +
                              ' to ' +
                              textValue.replace(fieldname, newfieldname))
                    field.text = textValue.replace(fieldname, newfieldname)
                    sibling = field.getnext()
                    if sibling is not None and sibling.text.find(
                            fieldname) >= 0:
                        textField2 = sibling.text
                        log.debug('changing parameterizedExpressionString ' +
                                  textField2 + ' to ' +
                                  textField2.replace(fieldname, newfieldname))
                        sibling.text = textField2.replace(
                            fieldname, newfieldname)
                else:
                    parent = field.getparent()
                    log.debug('removing parameter: ' + parent.get(Common.ID))
                    parent.getparent().remove(parent)
        # fix visible levels
        self.common.fixVisibleLevels(root=root,
                                     fieldname=fieldname,
                                     newfieldname=newfieldname,
                                     log=log)

    def removeRenameField(self, state_filename, jrxml_filename, fieldname,
                          newfieldname, log):
        if isinstance(fieldname, list):
            if newfieldname is None:
                newfieldname = []
                for _ in fieldname:
                    newfieldname.append('_')
            for s1, s2 in zip(fieldname, newfieldname):
                self.removeRenameFieldInJRXMLFile(jrxml_filename, s1, s2, log)
                self.removeRenameFieldInStateFile(state_filename, s1, s2, log)
        else:
            self.removeRenameFieldInJRXMLFile(jrxml_filename, fieldname,
                                              newfieldname, log)
            self.removeRenameFieldInStateFile(state_filename, fieldname,
                                              newfieldname, log)

    def removeRenameInputControlInMetadata(self, root, fieldname, newfieldname,
                                           log):
        # remove entire IC or fix query value and visible columns
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.LOCAL_RESOURCE +
                                Common.REPO_PATH_SEPARATOR +
                                'queryValueColumn'):
            textValue = field.text
            if textValue.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('Changing queryValueColumn ' + textValue +
                              ' to ' +
                              textValue.replace(fieldname, newfieldname))
                    field.text = textValue.replace(fieldname, newfieldname)
                    sibling = field.getprevious()
                    if sibling is not None and sibling.text.find(
                            fieldname) >= 0:
                        textValue2 = sibling.text
                        log.debug('Changing queryVisibleColumn ' + textValue2 +
                                  ' to ' +
                                  textValue2.replace(fieldname, newfieldname))
                        sibling.text = textValue2.replace(
                            fieldname, newfieldname)
                else:
                    parent = field.getparent()
                    log.debug('removing input control: ' +
                              parent[Common.ID_NODE_INDEX].text)
                    parent.getparent().remove(parent)
        # fix query
        if newfieldname is not None and newfieldname != '_':
            for query in root.xpath(Common.REPO_PATH_SEPARATOR +
                                    Common.REPO_PATH_SEPARATOR +
                                    Common.LOCAL_RESOURCE +
                                    Common.REPO_PATH_SEPARATOR +
                                    'queryString'):
                queryText = query.text
                if queryText.find(fieldname) >= 0:
                    log.debug('Changing query to ' +
                              queryText.replace(fieldname, newfieldname))
                    query.text = queryText.replace(fieldname, newfieldname)
            # fix name
            for name in root.xpath(Common.REPO_PATH_SEPARATOR +
                                   Common.REPO_PATH_SEPARATOR +
                                   Common.LOCAL_RESOURCE +
                                   Common.REPO_PATH_SEPARATOR + Common.NAME):
                nameText = name.text
                if nameText.find(fieldname) >= 0:
                    log.debug('Changing name ' + nameText + ' to ' +
                              nameText.replace(fieldname, newfieldname))
                    name.text = nameText.replace(fieldname, newfieldname)
            # fix folder
            for folder in root.xpath(Common.REPO_PATH_SEPARATOR +
                                     Common.REPO_PATH_SEPARATOR +
                                     Common.LOCAL_RESOURCE +
                                     Common.REPO_PATH_SEPARATOR + 'folder'):
                folderText = folder.text
                if folderText is not None and folderText.find(fieldname) >= 0:
                    log.debug('Changing folder ' + folderText + ' to ' +
                              folderText.replace(fieldname, newfieldname))
                    folder.text = folderText.replace(fieldname, newfieldname)

    def removeRenameInputControlInMetadataFile(self, metadata_filename,
                                               fieldname, newfieldname, log):
        log.debug('Checking metadata file for input controls to remove: ' +
                  metadata_filename[metadata_filename.
                                    rfind(Common.REPO_PATH_SEPARATOR) + 1:])
        with open(metadata_filename) as h:
            metadata_xml = h.read()
        metadata_tuple = self.common.removeDeclarationNode(
            xml_string=metadata_xml)
        metadata_xml = metadata_tuple[1]
        metadata_root = etree.fromstring(metadata_xml)
        if isinstance(fieldname, list):
            if newfieldname is None:
                newfieldname = []
                for _ in fieldname:
                    newfieldname.append('_')
            for s1, s2 in zip(fieldname, newfieldname):
                self.removeRenameInputControlInMetadata(root=metadata_root,
                                                        fieldname=s1,
                                                        newfieldname=s2,
                                                        log=log)
        else:
            self.removeRenameInputControlInMetadata(root=metadata_root,
                                                    fieldname=fieldname,
                                                    newfieldname=newfieldname,
                                                    log=log)
        metadata_bytea = etree.tostring(metadata_root,
                                        pretty_print=True,
                                        encoding='UTF-8')
        metadata_xml = "".join(map(chr, metadata_bytea))
        # re-insert original XML declaration
        metadata_xml = metadata_tuple[0] + metadata_xml
        if metadata_xml.endswith('\n'):
            metadata_xml = metadata_xml[0:len(metadata_xml) - 1]
        with open(metadata_filename, 'w') as h:
            h.write(metadata_xml)
コード例 #2
0
class FileFinderTest(unittest.TestCase):
    
    common = Common()
    
    DOMAIN_SCHEMA_FILE = """<?xml version="1.0" encoding="UTF-8"?>
<semanticLayerDataSource>
    <folder></folder>
    <name>Domain_Test</name>
    <schema>
        <localResource
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            exportedWithPermissions="false" dataFile="schema.data" xsi:type="fileResource">
            <folder></folder>
        </localResource>
    </schema>
</semanticLayerDataSource>
    """
    ADHOC_TOPIC_FILE = """<?xml version="1.0" encoding="UTF-8"?>
<dataDefinerUnit>
    <folder></folder>
    <name>Adhoc_Topic_Test</name>
    <mainReport>
        <localResource
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            exportedWithPermissions="false" dataFile="slJRXML.data" xsi:type="fileResource">
            <folder></folder>
        </localResource>
    </mainReport>
    <dataSource>
        <uri>/Domain_Test</uri>
    </dataSource>
    <resource>
        <localResource
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            exportedWithPermissions="false"
            dataFile="domainQuery.xml.data" xsi:type="fileResource">
            <folder></folder>
        </localResource>
    </resource>
</dataDefinerUnit>
    """
    ADHOC_VIEW_FILE = """<?xml version="1.0" encoding="UTF-8"?>
<adhocDataView exportedWithPermissions="true">
    <folder></folder>
    <name>Adhoc_View_Test</name>
    <dataSource>
        <uri>/Adhoc_Topic_Test</uri>
    </dataSource>
    <inputControl>
        <localResource
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            exportedWithPermissions="false" xsi:type="inputControl">
            <folder>/Adhoc_View_Test_files</folder>
            <name>store_country_1</name>
            <label>Country</label>
            <type>4</type>
            <mandatory>false</mandatory>
            <readOnly>false</readOnly>
            <visible>true</visible>
            <query>
                <localResource exportedWithPermissions="false" xsi:type="query">
                    <folder>/Adhoc_View_Test_files/store_country_1_files</folder>
                    <name>store_country_1</name>
                    <version>0</version>
                    <label>Country</label>
                    <language>domain</language>
                    <queryString>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;query xmlns="http://www.jaspersoft.com/2007/SL/XMLSchema"&gt;
  &lt;groupList&gt;
    &lt;group columnName="store_country" /&gt;
  &lt;/groupList&gt;
  &lt;queryFields&gt;
    &lt;queryField id="public_store.store_country" /&gt;
    &lt;queryField id="store_country" /&gt;
  &lt;/queryFields&gt;
&lt;/query&gt;
                        </queryString>
                    <dataSource>
                        <uri>/Domain_Test</uri>
                    </dataSource>
                </localResource>
            </query>
            <queryVisibleColumn>store_country</queryVisibleColumn>
            <queryValueColumn>store_country</queryValueColumn>
        </localResource>
    </inputControl>
    <resource>
        <uri>/domainQuery.xml</uri>
    </resource>
    <resource>
        <localResource
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            exportedWithPermissions="false" dataFile="topicJRXML.data" xsi:type="fileResource">
            <folder></folder>
            <name>topicJRXML</name>
        </localResource>
    </resource>
    <resource>
        <localResource
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            exportedWithPermissions="false" dataFile="stateXML.data" xsi:type="fileResource">
            <folder></folder>
            <name>stateXML</name>
        </localResource>
    </resource>
</adhocDataView>
    """
    REPORT_FILE = """<?xml version="1.0" encoding="UTF-8"?>
<reportUnit exportedWithPermissions="true">
    <folder></folder>
    <name>Report_Test</name>
    <mainReport>
        <localResource
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            exportedWithPermissions="false"
            dataFile="mainReportJrxml.data" xsi:type="fileResource">
            <folder></folder>
            <name>mainReportJrxml</name>
        </localResource>
    </mainReport>
    <dataSource>
        <uri>/Adhoc_View_Test</uri>
    </dataSource>
    <resource>
        <localResource
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            exportedWithPermissions="false" dataFile="stateXML.data" xsi:type="fileResource">
            <folder></folder>
            <name>stateXML</name>
        </localResource>
    </resource>
</reportUnit>
    """
    XML_EXT = '.xml'
    DOMAIN_NAME = 'Domain_Test'
    ADHOC_TOPIC_NAME = 'Adhoc_Topic_Test'
    ADHOC_VIEW_NAME = 'Adhoc_View_Test'
    REPORT_NAME = 'Report_Test'
    TMPPATH = 'tmp'

    def setUp(self):
        self.fileFinder = FileFinder()
        self.log = self.common.configureLogging()
        curr_folder = Common.REPO_PATH_SEPARATOR + self.TMPPATH
        self.fileFinder.resources_folder = curr_folder
        self.domain_metadata_file_path = curr_folder + Common.REPO_PATH_SEPARATOR + self.DOMAIN_NAME + self.XML_EXT
        self.adhoc_topic_metadata_file_path = curr_folder + Common.REPO_PATH_SEPARATOR + self.ADHOC_TOPIC_NAME + self.XML_EXT
        self.adhoc_view_metadata_file_path = curr_folder + Common.REPO_PATH_SEPARATOR + self.ADHOC_VIEW_NAME + self.XML_EXT
        self.report_metadata_file_path = curr_folder + Common.REPO_PATH_SEPARATOR + self.REPORT_NAME + self.XML_EXT
        directory = os.path.dirname(self.domain_metadata_file_path)
        if not os.path.exists(directory):
            os.makedirs(directory)
        with open(self.domain_metadata_file_path, 'w') as h1:
            h1.write(self.DOMAIN_SCHEMA_FILE)
        with open(self.adhoc_topic_metadata_file_path, 'w') as h2:
            h2.write(self.ADHOC_TOPIC_FILE)
        with open(self.adhoc_view_metadata_file_path, 'w') as h3:
            h3.write(self.ADHOC_VIEW_FILE)
        with open(self.report_metadata_file_path, 'w') as h4:
            h4.write(self.REPORT_FILE)

    def tearDown(self):
        try:
            os.remove(self.report_metadata_file_path)
            os.remove(self.adhoc_view_metadata_file_path)
            os.remove(self.adhoc_topic_metadata_file_path)
            os.remove(self.domain_metadata_file_path)
        except OSError:
            pass
        
    def testCheckDatasource(self):
        mock_root = MagicMock(name = 'mock_root')
        mock_root.tag.find.return_value = 0
        mock_node1 = MagicMock(name = 'mock_node1')
        mock_node1.text.find.return_value = 0
        mock_root.__getitem__.return_value = mock_node1
        self.assertTrue(self.fileFinder.checkDatasource(mock_root))
        
    def testCheckDatasourceDoesNotMatch(self):
        mock_root = MagicMock(name = 'mock_root')
        mock_root.tag.find.return_value = 0
        mock_node1 = MagicMock(name = 'mock_node1')
        mock_node1.text.find.return_value = -1
        mock_root.__getitem__.return_value = mock_node1
        self.assertFalse(self.fileFinder.checkDatasource(mock_root))
        
    def testCheckDatasourceCheckParent(self):
        self.fileFinder.domain_id = self.DOMAIN_NAME
        mock_root = MagicMock(name = 'mock_root');
        mock_root.tag.find.side_effect = [-1, 0]
        mock_node1 = MagicMock(name='mock_node1')
        mock_node1_text = PropertyMock(return_value=Common.REPO_PATH_SEPARATOR + self.DOMAIN_NAME)
        type(mock_node1).text = mock_node1_text
        node_list = [mock_node1]
        mock_root.xpath = MagicMock(side_effect=[node_list])
        self.assertTrue(self.fileFinder.checkDatasource(mock_root))

    def testFindDomainSchema(self):
        schema_filename = 'schema.data'
        self.fileFinder.domain_id = self.DOMAIN_NAME
        mock_grandchild = MagicMock(name='mock_grandchild')
        mock_grandchild_text = PropertyMock(return_value='')
        type(mock_grandchild).text = mock_grandchild_text
        mock_root = MagicMock(name = 'mock_root')
        mock_node1 = MagicMock(name = 'mock_node1')
        mock_node1.get.return_value = schema_filename
        mock_node1.__getitem__.return_value = mock_grandchild
        node_list = [mock_node1]
        mock_root.xpath = MagicMock(side_effect=[node_list])
        found_file = self.fileFinder.findDomainSchema(root=mock_root, log=self.log)
        self.assertIsNotNone(found_file, 'findDomainSchemaFile should not return none')
        self.assertEqual(Common.REPO_PATH_SEPARATOR + self.TMPPATH + Common.REPO_PATH_SEPARATOR + schema_filename, found_file, 'domain schema file not found')
            
    def testFindDomainSchemaFile(self):
        found_file = self.fileFinder.findDomainSchemaFile(metadata_filename=self.domain_metadata_file_path, log=self.log)
        self.assertIsNotNone(found_file, 'findDomainSchema should not return none')
        test_domain_schema_file = '/tmp/schema.data'
        self.assertEqual(test_domain_schema_file, found_file, 'domain schema file names do not match')
    
    def testFindAdHocTopic(self):
        state_file = 'stateXML.data'
        jrxml_file = 'slJRXML.data'
        self.fileFinder.domain_id = self.DOMAIN_NAME
        self.fileFinder.adhoc_topic_files_list = []
        mock_grandchild = MagicMock(name='mock_grandchild')
        mock_grandchild_text = PropertyMock(return_value=self.DOMAIN_NAME)
        type(mock_grandchild).text = mock_grandchild_text
        mock_grandchild.text = MagicMock(return_value=self.DOMAIN_NAME)
        mock_grandchild2 = MagicMock(name='mock_grandchild2')
        mock_grandchild2_text = PropertyMock(return_value=None)
        type(mock_grandchild2).text = mock_grandchild2_text 
        mock_root = MagicMock(name = 'mock_root')
        mock_root_tag = PropertyMock(return_value=Common.DOMAIN_METADATA_TAG)
        type(mock_root).tag = mock_root_tag
        mock_node1 = MagicMock(name = 'mock_node1')
        mock_node1.text.find.return_value = 0
        mock_node2 = MagicMock(name = 'mock_node2')
        mock_node2.__getitem__.return_value = mock_grandchild2
        mock_node2.get.return_value = jrxml_file
        mock_node2.text.find.return_value = 0
        node_list1 = [mock_node2]
        mock_node3 = MagicMock(name = 'mock_node3')
        mock_node3.__getitem__.return_value = mock_grandchild2
        mock_node3.get.return_value = state_file
        node_list2 = [mock_node3]
        mock_node4 = MagicMock(name='mock_node4')
        mock_node4_text = PropertyMock(return_value=self.ADHOC_TOPIC_NAME)
        type(mock_node4).text = mock_node4_text
        mock_root.__getitem__.side_effect = [mock_node1, mock_grandchild]
        mock_root.xpath = MagicMock(side_effect = [node_list1, node_list2])
        self.fileFinder.findAdhocTopic(root=mock_root, adhoc_topic_id=self.ADHOC_TOPIC_NAME, log=self.log)
        self.assertNotEqual([], self.fileFinder.adhoc_topic_files_list, 'Ad Hoc topic files not found')
        self.assertEqual(Common.REPO_PATH_SEPARATOR + self.TMPPATH + Common.REPO_PATH_SEPARATOR + state_file, self.fileFinder.adhoc_topic_files_list[0][0], 'state file not found')
        self.assertEqual(Common.REPO_PATH_SEPARATOR + self.TMPPATH + Common.REPO_PATH_SEPARATOR +  jrxml_file, self.fileFinder.adhoc_topic_files_list[0][1], 'jrxml file not found')
        
    def testFindAdHocTopicIDDoesNotMatch(self):
        self.fileFinder.adhoc_topic_files_list = []
        mock_root = MagicMock(name = 'mock_root')
        mock_node1 = MagicMock(name = 'mock_node1')
        mock_node1.text.find.return_value = -1
        mock_root.__getitem__.return_value = mock_node1
        self.fileFinder.findAdhocTopic(root=mock_root, adhoc_topic_id=self.ADHOC_TOPIC_NAME, log=self.log)
        self.assertEqual([], self.fileFinder.adhoc_topic_files_list, 'ad hoc topic files should not be found')
            
    def testFindAdHocTopicFiles(self):
        self.fileFinder.adhoc_topic_files_list = []
        self.fileFinder.domain_id = self.DOMAIN_NAME
        self.fileFinder.findAdhocTopicFiles(metadata_filename=self.adhoc_topic_metadata_file_path, adhoc_topic_id=self.ADHOC_TOPIC_NAME, log=self.log)
        self.assertNotEqual([], self.fileFinder.adhoc_topic_files_list, 'Ad Hoc topic files list is empty')
        test_adhoc_topic_state_file = '/tmp/domainQuery.xml.data'
        self.assertEqual(test_adhoc_topic_state_file, self.fileFinder.adhoc_topic_files_list[0][0], 'ad hoc topic state file names do not match')
        test_adhoc_topic_report_file = '/tmp/slJRXML.data'
        self.assertEqual(test_adhoc_topic_report_file, self.fileFinder.adhoc_topic_files_list[0][1], 'jrxml report file names do not match')
        
    def testFindAdHocTopicFilesIDDoesNotMatch(self):
        self.fileFinder.adhoc_topic_files_list = []
        self.fileFinder.domain_id = self.DOMAIN_NAME
        self.fileFinder.findAdhocTopicFiles(metadata_filename=self.adhoc_topic_metadata_file_path, adhoc_topic_id='Some_Other_Topic', log=self.log)
        self.assertEqual([], self.fileFinder.adhoc_topic_files_list, 'Ad Hoc topic files should not be found')
        
    def testFindAdHocView(self):
        state_filename = 'stateXML.data'
        jrxml_filename = 'topicJRXML.data'
        self.fileFinder.adhoc_view_files_list = []
        self.fileFinder.domain_id = self.DOMAIN_NAME
        mock_grandchild = MagicMock(name='mock_grandchild')
        mock_grandchild_text = PropertyMock(return_value='')
        type(mock_grandchild).text = mock_grandchild_text
        mock_root = MagicMock(name = 'mock_root')
        mock_root.tag.find.return_value = 0
        mock_node1 = MagicMock(name = 'mock_node1')
        mock_node1.text.find.return_value = 0
        mock_node1.get.return_value = state_filename
        mock_node2 = MagicMock(name = 'mock_node2')
        mock_node2.get.return_value = jrxml_filename
        mock_node3 = MagicMock(name = 'mock_node3')
        mock_node3_text = PropertyMock(return_value=state_filename)
        type(mock_node3).text = mock_node3_text
        mock_node4 = MagicMock(name = 'mock_node4')
        mock_node4_text = PropertyMock(return_value=jrxml_filename)
        type(mock_node4).text = mock_node4_text
        mock_node1.__getitem__.side_effect = [mock_node3, mock_grandchild]
        mock_node2.__getitem__.side_effect = [mock_node4, mock_grandchild]
        node_list = [mock_node1, mock_node2]
        mock_root.__getitem__.side_effect = [mock_node1, mock_node1]
        mock_root.xpath = MagicMock(side_effect = [node_list, []])
        self.fileFinder.findAdhocView(root=mock_root, adhoc_view_id=self.ADHOC_VIEW_NAME, log=self.log)
        self.assertNotEqual([], self.fileFinder.adhoc_view_files_list, 'Ad Hoc view files not found')
        self.assertEqual(Common.REPO_PATH_SEPARATOR + self.TMPPATH + Common.REPO_PATH_SEPARATOR + state_filename, self.fileFinder.adhoc_view_files_list[0][0], 'state file not found')
        self.assertEqual(Common.REPO_PATH_SEPARATOR + self.TMPPATH + Common.REPO_PATH_SEPARATOR +  jrxml_filename, self.fileFinder.adhoc_view_files_list[0][1], 'jrxml file not found')
    
    def testFindAdHocViewIDDoesNotMatch(self):
        mock_root = MagicMock(name = 'mock_root')
        mock_node1 = MagicMock(name = 'mock_node1')
        mock_node1.text.find.return_value = -1
        mock_root.__getitem__.return_value = mock_node1
        self.fileFinder.findAdhocView(root=mock_root, adhoc_view_id=self.ADHOC_VIEW_NAME, log=self.log)
        self.assertEqual([], self.fileFinder.adhoc_view_files_list, 'ad hoc view files should not have been found')
            
    def testFindAdHocViewFiles(self):
        self.fileFinder.domain_id = self.DOMAIN_NAME
        self.fileFinder.adhoc_view_files_list = []
        self.fileFinder.findAdhocViewFiles(metadata_filename=self.adhoc_view_metadata_file_path, adhoc_view_id=self.ADHOC_VIEW_NAME, log=self.log)
        self.assertNotEqual([], self.fileFinder.adhoc_view_files_list, 'Ad Hoc view files not found')
        test_adhoc_view_state_file = '/tmp/stateXML.data'
        self.assertEqual(test_adhoc_view_state_file, self.fileFinder.adhoc_view_files_list[0][0], 'ad hoc view state file names do not match')
        test_adhoc_view_report_file = '/tmp/topicJRXML.data'
        self.assertEqual(test_adhoc_view_report_file, self.fileFinder.adhoc_view_files_list[0][1], 'jrxml report file names do not match')
        
    def testFindAdHocViewFilesIDDoesNotMatch(self):
        self.fileFinder.findAdhocViewFiles(metadata_filename=self.adhoc_view_metadata_file_path, adhoc_view_id='Some_Other_View', log=self.log)
        self.assertEqual([], self.fileFinder.adhoc_view_files_list, 'Ad Hoc view files should not be found')
        
    def testFindReport(self):
        state_filename = 'stateXML.data'
        jrxml_filename = 'mainReportJrxml.data'
        self.fileFinder.report_list = []
        mock_grandchild = MagicMock(name='mock_grandchild')
        mock_grandchild_text = PropertyMock(return_value=self.TMPPATH)
        type(mock_grandchild).text = mock_grandchild_text
        mock_grandchild2 = MagicMock(name='mock_grandchild2')
        mock_grandchild2_text = PropertyMock(return_value=None)
        type(mock_grandchild2).text = mock_grandchild2_text
        mock_root = MagicMock(name = 'mock_root')
        mock_root.tag.find.return_value = 0
        mock_node1 = MagicMock(name = 'mock_node1')
        mock_node1.text.find.return_value = 0
        mock_node2 = MagicMock(name = 'mock_node2')
        mock_node2.text.find.return_value = 0
        mock_node2.get.return_value = state_filename
        mock_node2.__getitem__.return_value = mock_grandchild2
        node_list1 = [mock_node2]
        mock_node3 = MagicMock(name = 'mock_node3')
        mock_node3.get.return_value = jrxml_filename
        mock_node3.__getitem__.return_value = mock_grandchild2
        mock_root.__getitem__.return_value = mock_node1
        node_list2 = [mock_node3]
        mock_root.xpath = MagicMock(side_effect = [node_list2, node_list1])
        self.fileFinder.findReport(root=mock_root, report_id=self.REPORT_NAME, log=self.log)
        self.assertNotEqual([], self.fileFinder.report_list, 'Report files not found')
        self.assertEqual(Common.REPO_PATH_SEPARATOR + self.TMPPATH + Common.REPO_PATH_SEPARATOR + state_filename, self.fileFinder.report_list[0][0], 'state filenames do not match')
        self.assertEqual(Common.REPO_PATH_SEPARATOR + self.TMPPATH + Common.REPO_PATH_SEPARATOR + jrxml_filename, self.fileFinder.report_list[0][1], 'report filenames do not match')
        
    def testFindStaticReport(self):
        jrxml_filename = 'main_jrxml.data'
        self.fileFinder.report_list = []
        mock_grandchild = MagicMock(name='mock_grandchild')
        mock_grandchild.text = MagicMock(return_value=self.TMPPATH)
        mock_grandchild2 = MagicMock(name='mock_grandchild2')
        mock_grandchild2_text = PropertyMock(return_value=None)
        type(mock_grandchild2).text = mock_grandchild2_text
        mock_root = MagicMock(name = 'mock_root')
        mock_root.tag.find.return_value = 0
        mock_node1 = MagicMock(name = 'mock_node1')
        mock_node1.text.find.return_value = 0
        mock_node2 = MagicMock(name = 'mock_node3')
        mock_node2.get.return_value = jrxml_filename
        mock_node2.__getitem__.return_value = mock_grandchild2
        mock_root.__getitem__.return_value = mock_node1
        node_list1 = [mock_node2]
        mock_root.xpath = MagicMock(side_effect = [node_list1, []])
        self.fileFinder.findReport(root=mock_root, report_id=self.REPORT_NAME, log=self.log)
        self.assertNotEqual([], self.fileFinder.report_list, 'Report files not found')
        self.assertIsNone(self.fileFinder.report_list[0][0], 'state filename is not None')
        self.assertEqual(Common.REPO_PATH_SEPARATOR + self.TMPPATH + Common.REPO_PATH_SEPARATOR + jrxml_filename, self.fileFinder.report_list[0][1], 'jrxml filenames do not match')
        
    def testFindReportIDDoesNotMatch(self):
        self.fileFinder.adhoc_view_files_list = []
        self.fileFinder.report_list = []
        mock_root = MagicMock(name = 'mock_root')
        mock_node1 = MagicMock(name = 'mock_node1')
        mock_node1.text.find.return_value = -1
        mock_root.__getitem__.return_value = mock_node1
        self.fileFinder.findReport(root=mock_root, report_id=self.REPORT_NAME, log=self.log)
        self.assertEqual([], self.fileFinder.report_list, 'report files should not have been found')
            
    def testFindReportFiles(self):
        self.fileFinder.domain_id = self.DOMAIN_NAME
        self.fileFinder.findReportFiles(metadata_filename=self.report_metadata_file_path, report_id=self.REPORT_NAME, log=self.log)
        self.assertNotEqual([], self.fileFinder.report_list, 'report files not found')
        test_report_state_file = '/tmp/stateXML.data'
        self.assertEqual(test_report_state_file, self.fileFinder.report_list[0][0], 'report state file names do not match')
        test_report_jrxml_file = '/tmp/mainReportJrxml.data'
        self.assertEqual(test_report_jrxml_file, self.fileFinder.report_list[0][1], 'jrxml report file names do not match')
コード例 #3
0
class DomainAction():
    
    common = Common()
    
    def renameOrRemoveFieldFromSchema(self, root, fieldname, newfieldname, newdbcolname, log):
        # if field is foreign key
        for field in root.xpath(Common.REPO_PATH_SEPARATOR + Common.REPO_PATH_SEPARATOR + Common.JOIN_STRING, namespaces=Common.DOMAIN_QUERY_NAMESPACE):
            if field.text.find(fieldname) >= 0:
                raise ValueError('We will probably be able to handle removing key fields in the future, but for now it is not allowed')
        # if field is an item
        for field in root.xpath(Common.REPO_PATH_SEPARATOR + Common.REPO_PATH_SEPARATOR + Common.ITEM, namespaces=Common.DOMAIN_QUERY_NAMESPACE):
            idValue = field.get(Common.ID)
            if idValue.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming item ' + idValue + ' to ' + idValue.replace(fieldname, newfieldname))
                    field.attrib[Common.ID] = idValue.replace(fieldname, newfieldname)
                    field.attrib[Common.RESOURCE_ID] = field.get(Common.RESOURCE_ID).replace(fieldname, newfieldname)
                    # change the label only if the label ID property isn't set (ignore if using I18N)
                    if len(field.get(Common.LABEL_ID)) == 0:
                        field.attrib[Common.LABEL] = field.get(Common.LABEL).replace(fieldname, newfieldname)
                else:
                    log.debug('removing item: ' + idValue)
                    field.getparent().remove(field)
        # if field is a field
        for field in root.xpath(Common.REPO_PATH_SEPARATOR + Common.REPO_PATH_SEPARATOR + Common.FIELD, namespaces=Common.DOMAIN_QUERY_NAMESPACE):
            idValue = field.get(Common.ID)
            if idValue.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming field ' + idValue + ' to ' + idValue.replace(fieldname, newfieldname))
                    field.attrib[Common.ID] = idValue.replace(fieldname, newfieldname)
                    if newdbcolname is not None and newdbcolname != '_':
                        log.debug('Renaming field DB column name to: ' + newdbcolname)
                        field.attrib[Common.FIELD_DB_NAME] = newdbcolname
                else:
                    log.debug('removing field: ' + idValue)
                    field.getparent().remove(field)
    
    def removeOrRenameField(self, filename, fieldname, newfieldname, newdbcolname, log):
        log.debug('Preparing to remove field(s) from domain schema file: ' + filename[filename.rfind(Common.REPO_PATH_SEPARATOR) + 1:])
        with open(filename, 'r', encoding='utf-8') as h:
            schema_xml = h.read()
        schema_tuple = self.common.removeDeclarationNode(xml_string=schema_xml)
        schema_root = etree.fromstring(schema_tuple[1])
        if isinstance(fieldname, list):
            if newfieldname is None:
                newfieldname = []
                for _ in fieldname:
                    newfieldname.append('_')
            if newdbcolname is None:
                newdbcolname = []
                for _ in fieldname:
                    newdbcolname.append('_')
            for s1, s2, s3 in zip(fieldname, newfieldname, newdbcolname):
                self.renameOrRemoveFieldFromSchema(root=schema_root, fieldname=s1, newfieldname=s2, newdbcolname=s3, log=log)
        else:
            self.renameOrRemoveFieldFromSchema(root=schema_root, fieldname=fieldname, newfieldname=newfieldname, newdbcolname=newdbcolname, log=log)
        schema_bytea = etree.tostring(schema_root, pretty_print=True, encoding='UTF-8')
        schema_xml = "".join(map(chr, schema_bytea))
        schema_xml = schema_tuple[0] + schema_xml
        with open(filename, 'w', encoding='utf-8') as h:
            h.write(schema_xml)
コード例 #4
0
class DomainMetadataModHelper():

    common = Common()
    server_URL = None
    server_pass = None
    session = None
    folderpath = None
    domain_id = None
    fieldname = None
    newfieldname = None
    newdbcolname = None
    
    def connectToServer(self, log):
        self.session = requests.post(self.server_URL + Common.LOGIN_PATH, data={Common.J_USERNAME:'******', Common.J_PASSWORD:self.server_pass})
        if self.session.status_code == 401:
            log.error('Error logging into JasperReports Server: Unauthorized')
            quit()
        elif self.session.status_code == 404:
            log.error('Error logging into JasperReports Server: no server found at location ' + self.server_URL)
            quit()
        elif self.session.status_code == 302:
            log.error('Error logging into JasperReports Server: License expired')
            quit()
        elif self.session.status_code != 200:
            self.session.raise_for_status()
            quit()
        
    def downloadExport(self, log):
        log.debug('starting repository export...')
        descriptor = { 'parameters':['everything']}
        startResult = requests.post(self.server_URL + Common.EXPORT_START_PATH, json=descriptor, cookies=self.session.cookies)
        if startResult.status_code == 200:
            startResultText = startResult.text
            startResultTuple = self.common.removeDeclarationNode(startResultText)
            startResultXml = etree.fromstring(startResultTuple[1])
            for node in startResultXml.xpath(Common.REPO_PATH_SEPARATOR + Common.REPO_PATH_SEPARATOR + Common.ID):
                exportProcessID = node.text
                break
            if exportProcessID != None:
                log.debug('export process id: ' + exportProcessID)
                phase = Common.PHASE_INPROGRESS_STATUS
                while phase != Common.PHASE_READY_STATUS:
                    log.debug('waiting 5 seconds...')
                    time.sleep(Common.FIVE_SECONDS) 
                    pollingResult = requests.get(self.server_URL + Common.REPO_PATH_SEPARATOR + Common.REST_V2 + 
                                   Common.REPO_PATH_SEPARATOR + Common.EXPORT + 
                                   Common.REPO_PATH_SEPARATOR + exportProcessID + 
                                   Common.REPO_PATH_SEPARATOR + Common.STATE, cookies=self.session.cookies)
                    if pollingResult.status_code == 200:
                        pollingResultText = pollingResult.text
                        pollingResultTuple = self.common.removeDeclarationNode(pollingResultText)
                        pollingResultXml = etree.fromstring(pollingResultTuple[1])
                        for node in pollingResultXml.xpath(Common.REPO_PATH_SEPARATOR + Common.REPO_PATH_SEPARATOR + Common.PHASE):
                            phase = node.text
                            break
                    else:
                        pollingResult.raise_for_status()
                        quit()
                    if phase == Common.PHASE_FAILURE_STATUS:
                        for node in pollingResultXml.xpath(Common.REPO_PATH_SEPARATOR + Common.REPO_PATH_SEPARATOR + Common.MESSAGE):
                            message = node.text
                            break
                        log.error('Error while exporting the repository:  ' + message)
                        quit()
                if phase == Common.PHASE_READY_STATUS:
                    _, tmpfile = tempfile.mkstemp()
                    tmpfilefile = tmpfile[tmpfile.rfind(Common.REPO_PATH_SEPARATOR) + 1:]
                    # check to see if we're on Windows
                    if tmpfilefile.find(Common.WINDOWS_PATH_SEPARATOR) >= 0:
                        tmpfilefile = tmpfilefile[tmpfilefile.rfind(Common.WINDOWS_PATH_SEPARATOR) + 1:]
                    log.debug('export finished, starting download to ' + tmpfile)
                    downloadRestCall = (self.server_URL + Common.REPO_PATH_SEPARATOR + Common.REST_V2 +
                                    Common.REPO_PATH_SEPARATOR + Common.EXPORT +
                                    Common.REPO_PATH_SEPARATOR + exportProcessID + 
                                    Common.REPO_PATH_SEPARATOR + tmpfilefile)
                    log.debug('download rest API call: ' + downloadRestCall)
                    savingResult = requests.get(downloadRestCall, cookies=self.session.cookies)
                    if savingResult.status_code != 200:
                        savingResult.raise_for_status()
                        quit()
                    else:
                        with open(tmpfile, 'wb') as h:
                            h.write(savingResult.content)
                        tmpdir = tempfile.mkdtemp()
                        zipRef = zipfile.ZipFile(tmpfile, 'r')
                        log.debug('extracting zip archive ' + tmpfile + ' to ' + tmpdir)
                        zipRef.extractall(tmpdir)
                        zipRef.close()
                        log.debug('finished extracting, removing zip archive')
                        try:
                            os.remove(tmpfile)
                        except OSError as err:
                            log.error('unable to remove zip archive: {0}'.format(err))
                        log.debug('setting folderpath: ' + tmpdir)
                        self.folderpath = tmpdir
        
    def uploadImport(self, log):
        _, tmpfile = tempfile.mkstemp()
        log.debug('creating import archive at: ' + tmpfile)
        shutil.make_archive(tmpfile, 'zip', self.folderpath)
        log.debug('importing zip file into repository...')
        params =  {'update':'true','skipUserUpdate':'true','includeAccessEvents':'false','includeAuditEvents':'false','includeMonitoringEvents':'false','includeServerSetting':'false'}
        if tmpfile.rfind('/') == -1:
            tmpfilename = tmpfile[tmpfile.rfind('\\')+1:]
        else:
            tmpfilename = tmpfile[tmpfile.rfind('/')+1:]
        headers = {'Content-Disposition':'form-data; name="File"; filename="' + tmpfilename + '"','Content-Type':'application/zip','X-Remote-Domain':'true'}
        with open(tmpfile + Common.ZIP_EXT, 'rb') as h:
            data = h.read()
        startResult = requests.post(self.server_URL + Common.IMPORT_START_PATH, params=params, headers=headers, data=data, cookies=self.session.cookies)
        if startResult.status_code == 200:
            startResultText = startResult.text
            startResultTuple = self.common.removeDeclarationNode(startResultText)
            startResultXml = etree.fromstring(startResultTuple[1])
            for node in startResultXml.xpath(Common.REPO_PATH_SEPARATOR + Common.REPO_PATH_SEPARATOR + Common.ID):
                importProcessID = node.text
                break
            if importProcessID != None:
                log.debug('import process id: ' + importProcessID)
                phase = Common.PHASE_INPROGRESS_STATUS
                while phase != Common.PHASE_READY_STATUS:
                    log.debug('waiting 5 seconds...')
                    time.sleep(Common.FIVE_SECONDS) 
                    pollingResult = requests.get(self.server_URL + Common.REPO_PATH_SEPARATOR + Common.REST_V2 + 
                                   Common.REPO_PATH_SEPARATOR + Common.IMPORT + 
                                   Common.REPO_PATH_SEPARATOR + importProcessID + 
                                   Common.REPO_PATH_SEPARATOR + Common.STATE, cookies=self.session.cookies)
                    if pollingResult.status_code == 200:
                        pollingResultText = pollingResult.text
                        pollingResultTuple = self.common.removeDeclarationNode(pollingResultText)
                        pollingResultXml = etree.fromstring(pollingResultTuple[1])
                        for node in pollingResultXml.xpath(Common.REPO_PATH_SEPARATOR + Common.REPO_PATH_SEPARATOR + Common.PHASE):
                            phase = node.text
                            break
                    else:
                        pollingResult.raise_for_status()
                        quit()
                    if phase == Common.PHASE_FAILURE_STATUS:
                        for node in pollingResultXml.xpath(Common.REPO_PATH_SEPARATOR + Common.REPO_PATH_SEPARATOR + Common.MESSAGE):
                            message = node.text
                            break
                        log.error('Error while exporting the repository:  ' + message)
                        quit()
                if phase == Common.PHASE_READY_STATUS:
                    log.debug('import complete, cleaning up temporary files...')
                    shutil.rmtree(self.folderpath)
                    os.remove(tmpfile)
                    os.remove(tmpfile + Common.ZIP_EXT)
        
    def processInputs(self, inputs):
        log = self.common.configureLogging()
        log.debug('inputs provided: ' + str(inputs))
        if len(inputs) < 5:
            raise ValueError(Common.NOT_ENOUGH_VALUES)
        if inputs[1].find('http') == -1:
            raise ValueError(Common.PROTOCOL_MISSING)
            quit()
        else:
            self.server_URL = inputs[1]
            self.server_pass = inputs[2]
            self.domain_id = inputs[3]
            self.fieldname = inputs[4]
            if self.fieldname.find(',') > 0:
                self.fieldname = self.fieldname.split(',')
            if len(inputs) >= 6:
                self.newfieldname = inputs[5]
                if self.newfieldname.find(',') > 0:
                    self.newfieldname = self.newfieldname.split(',')
                    if not isinstance(self.fieldname, list):
                        raise ValueError('Both the old and new field name parameters must be comma-separated lists')
                    if len(self.newfieldname) != len(self.fieldname):
                        raise ValueError('both the old and new field name parameter lists must be the same length')
            if len(inputs) >= 7:
                self.newdbcolname = inputs[6]
                if self.newdbcolname.find(',') > 0:
                    self.newdbcolname = self.newdbcolname.split(',')
                    if not isinstance(self.fieldname, list) or not isinstance(self.newfieldname, list):
                        raise ValueError('Old and new field name and database column name parameters must be comma-separated lists')
                    if len(self.newdbcolname) != len(self.fieldname) or len(self.newdbcolname) != len(self.newfieldname):
                        raise ValueError('Old and new field name and database column name parameter lists must be the same length')
            else:
                # use the new field name items as the database column items
                self.newdbcolname = self.newfieldname
        return log
        
コード例 #5
0
class FileFinder():

    common = Common()
    domainAction = DomainAction()
    adhocAction = AdhocAction()
    reportAction = ReportAction()
    domain_id = None
    resources_folder = None
    adhoc_topic_files_list = []
    adhoc_view_files_list = []
    report_list = []

    def findDomainSchema(self, root, log):
        for child in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.LOCAL_RESOURCE):
            folderPath = child[Common.STATE_FILE_NODE_INDEX].text
            if folderPath is None:
                folderPath = ''
            domainSchemaFile = self.resources_folder + folderPath + Common.REPO_PATH_SEPARATOR + child.get(
                Common.DATA_FILE)
            log.debug('found domain schema file: ' + domainSchemaFile)
            return domainSchemaFile

    def findDomainSchemaFile(self, metadata_filename, log):
        with open(metadata_filename) as h:
            metadata_xml = h.read()
        metadata_tuple = self.common.removeDeclarationNode(
            xml_string=metadata_xml)
        metadata_root = etree.fromstring(metadata_tuple[1])
        return self.findDomainSchema(root=metadata_root, log=log)

    def findAdhocTopic(self, root, adhoc_topic_id, log):
        jrxmlfile = None
        statefile = None
        adhoc_topic_id_node = root[Common.ID_NODE_INDEX]
        if adhoc_topic_id_node.text.find(
                adhoc_topic_id) >= 0 and self.checkDatasource(root=root):
            for child in root.xpath(Common.REPO_PATH_SEPARATOR +
                                    Common.REPO_PATH_SEPARATOR + 'mainReport' +
                                    Common.REPO_PATH_SEPARATOR +
                                    Common.LOCAL_RESOURCE):
                folderPath = child[Common.STATE_FILE_NODE_INDEX].text
                if folderPath is None:
                    folderPath = ''
                jrxmlfile = self.resources_folder + folderPath + Common.REPO_PATH_SEPARATOR + child.get(
                    Common.DATA_FILE)
                log.debug('found JRXML file: ' + jrxmlfile)
            for child in root.xpath(Common.REPO_PATH_SEPARATOR +
                                    Common.REPO_PATH_SEPARATOR + 'resource' +
                                    Common.REPO_PATH_SEPARATOR +
                                    Common.LOCAL_RESOURCE):
                folderPath = child[Common.STATE_FILE_NODE_INDEX].text
                if folderPath is None:
                    folderPath = ''
                statefile = self.resources_folder + folderPath + Common.REPO_PATH_SEPARATOR + child.get(
                    Common.DATA_FILE)
                log.debug('found state file: ' + statefile)
        if statefile is not None and jrxmlfile is not None:
            self.adhoc_topic_files_list.append([statefile, jrxmlfile])

    def findAdhocTopicFiles(self, metadata_filename, adhoc_topic_id, log):
        with open(metadata_filename) as h:
            metadata_xml = h.read()
        metadata_tuple = self.common.removeDeclarationNode(
            xml_string=metadata_xml)
        metadata_root = etree.fromstring(metadata_tuple[1])
        self.findAdhocTopic(root=metadata_root,
                            adhoc_topic_id=adhoc_topic_id,
                            log=log)

    def findAdhocView(self, root, adhoc_view_id, log):
        jrxmlfile = None
        statefile = None
        reportJrxmlfile = None
        reportStatefile = None
        adhoc_view_id_node = root[Common.ID_NODE_INDEX]
        if adhoc_view_id_node.text.find(
                adhoc_view_id) >= 0 and self.checkDatasource(root):
            for child in root.xpath(Common.REPO_PATH_SEPARATOR +
                                    Common.ADHOC_VIEW_TAG +
                                    Common.REPO_PATH_SEPARATOR +
                                    Common.RESOURCE_TAG +
                                    Common.REPO_PATH_SEPARATOR +
                                    Common.LOCAL_RESOURCE):
                secondchild = child[Common.ID_NODE_INDEX]
                folderPath = child[Common.STATE_FILE_NODE_INDEX].text
                if folderPath is None:
                    folderPath = ''
                if secondchild.text.find(Common.STATE_XML) >= 0:
                    statefile = self.resources_folder + folderPath + Common.REPO_PATH_SEPARATOR + child.get(
                        Common.DATA_FILE)
                    log.debug('found state file: ' + statefile)
                elif secondchild.text.find(Common.TOPIC_JRXML) >= 0:
                    jrxmlfile = self.resources_folder + folderPath + Common.REPO_PATH_SEPARATOR + child.get(
                        Common.DATA_FILE)
                    log.debug('found jrxml file: ' + jrxmlfile)
            # check to see if there's a nested report used for a dashboard
            for child in root.xpath(Common.REPO_PATH_SEPARATOR +
                                    Common.ADHOC_VIEW_TAG +
                                    Common.REPO_PATH_SEPARATOR + 'reports' +
                                    Common.REPO_PATH_SEPARATOR +
                                    Common.LOCAL_RESOURCE +
                                    Common.REPO_PATH_SEPARATOR +
                                    Common.RESOURCE_TAG +
                                    Common.REPO_PATH_SEPARATOR +
                                    Common.LOCAL_RESOURCE):
                secondchild = child[Common.ID_NODE_INDEX]
                folderPath = child[Common.STATE_FILE_NODE_INDEX].text
                if folderPath is None:
                    folderPath = ''
                if secondchild.text.find(Common.STATE_XML) >= 0:
                    reportStatefile = self.resources_folder + folderPath + Common.REPO_PATH_SEPARATOR + child.get(
                        Common.DATA_FILE)
                    log.debug('found dashboard report state file: ' +
                              reportStatefile)
                elif secondchild.text.find(Common.MAIN_REPORT_JRXML) >= 0:
                    reportJrxmlfile = self.resources_folder + folderPath + Common.REPO_PATH_SEPARATOR + child.get(
                        Common.DATA_FILE)
                    log.debug('found dashboard report jrxml file: ' +
                              jrxmlfile)
        if statefile is not None and jrxmlfile is not None:
            self.adhoc_view_files_list.append([statefile, jrxmlfile])
            if reportStatefile is not None and reportJrxmlfile is not None:
                self.report_list.append([reportStatefile, reportJrxmlfile])
            return True
        else:
            return False

    def findAdhocViewFiles(self, metadata_filename, adhoc_view_id, log):
        with open(metadata_filename) as h:
            metadata_xml = h.read()
        metadata_tuple = self.common.removeDeclarationNode(
            xml_string=metadata_xml)
        metadata_root = etree.fromstring(metadata_tuple[1])
        return self.findAdhocView(root=metadata_root,
                                  adhoc_view_id=adhoc_view_id,
                                  log=log)

    def findReport(self, root, report_id, log):
        jrxmlfile = None
        statefile = None
        report_id_node = root[Common.ID_NODE_INDEX]
        if report_id_node.text.find(report_id) >= 0 and self.checkDatasource(
                root):
            for child in root.xpath(Common.REPO_PATH_SEPARATOR +
                                    Common.REPO_PATH_SEPARATOR + 'mainReport' +
                                    Common.REPO_PATH_SEPARATOR +
                                    Common.LOCAL_RESOURCE):
                folderPath = child[Common.STATE_FILE_NODE_INDEX].text
                if folderPath is None:
                    folderPath = ''
                jrxmlfile = self.resources_folder + folderPath + Common.REPO_PATH_SEPARATOR + child.get(
                    Common.DATA_FILE)
                log.debug('found jrxml file: ' + jrxmlfile)
            for child in root.xpath(Common.REPO_PATH_SEPARATOR +
                                    Common.REPO_PATH_SEPARATOR + 'resource' +
                                    Common.REPO_PATH_SEPARATOR +
                                    Common.LOCAL_RESOURCE):
                if child.get(Common.DATA_FILE) == Common.STATE_DATAFILE:
                    folderPath = child[Common.STATE_FILE_NODE_INDEX].text
                    if folderPath is None:
                        folderPath = ''
                    statefile = self.resources_folder + folderPath + Common.REPO_PATH_SEPARATOR + child.get(
                        Common.DATA_FILE)
                    log.debug('found state file: ' + statefile)
                    break
        if statefile is not None and jrxmlfile is not None:
            self.report_list.append([statefile, jrxmlfile])
            return False
        elif jrxmlfile is not None:
            # static report with domain data source
            self.report_list.append([None, jrxmlfile])
            return True
        else:
            return False

    def findReportFiles(self, metadata_filename, report_id, log):
        with open(metadata_filename) as h:
            metadata_xml = h.read()
        metadata_tuple = self.common.removeDeclarationNode(
            xml_string=metadata_xml)
        metadata_root = etree.fromstring(metadata_tuple[1])
        return self.findReport(root=metadata_root,
                               report_id=report_id,
                               log=log)

    def checkRootNodeTag(self, root_tag):
        if root_tag.find(Common.DOMAIN_METADATA_TAG) >= 0 or root_tag.find(
                Common.ADHOC_TOPIC_TAG) >= 0 or root_tag.find(
                    Common.ADHOC_VIEW_TAG) >= 0 or root_tag.find(
                        Common.REPORT_TAG) >= 0:
            return True
        else:
            return False

    def checkDatasource(self, root):
        if root.tag.find(self.common.DOMAIN_METADATA_TAG) >= 0:
            if root[Common.ID_NODE_INDEX].text.find(self.domain_id) >= 0:
                return True
            else:
                return False
        else:
            # check parent
            for child in root.xpath(Common.REPO_PATH_SEPARATOR +
                                    Common.REPO_PATH_SEPARATOR +
                                    Common.DATA_SOURCE +
                                    Common.REPO_PATH_SEPARATOR + 'uri'):
                with open(self.resources_folder + child.text + '.xml') as h:
                    metadata_xml = h.read()
                metadata_tuple = self.common.removeDeclarationNode(
                    metadata_xml)
                metadata_root = etree.fromstring(metadata_tuple[1])
                return self.checkDatasource(metadata_root)

    def walk(self, dmmHelper, log):
        self.walk2(folderpath=dmmHelper.folderpath,
                   domain_id=dmmHelper.domain_id,
                   fieldname=dmmHelper.fieldname,
                   newfieldname=dmmHelper.newfieldname,
                   newdbcolname=dmmHelper.newdbcolname,
                   log=log)

    def walk2(self, folderpath, domain_id, fieldname, newfieldname,
              newdbcolname, log):
        self.domain_id = domain_id
        for root, _, files in os.walk(folderpath, topdown=True):
            for filename in files:
                if filename.find(Common.PROPERTIES_EXT) == -1:
                    xml_file = None
                    filepath = os.path.join(root, filename)
                    log.info('Inspecting file: ' + filepath)
                    if self.resources_folder is None and str(root).find(
                            Common.RESOURCES_FOLDER) > -1:
                        self.resources_folder = str(
                            root)[:str(root).find(Common.RESOURCES_FOLDER) +
                                  len(Common.RESOURCES_FOLDER)]
                    with open(filepath) as h:
                        try:
                            xml_file = h.read()
                        except UnicodeDecodeError:
                            log.debug('Ignoring non-text file: ' + filepath)
                    if xml_file != None:
                        xml_tuple = self.common.removeDeclarationNode(
                            xml_string=xml_file)
                        root_node = None
                        try:
                            root_node = etree.fromstring(xml_tuple[1])
                        except etree.XMLSyntaxError:
                            log.debug('Ignoring non-XML file: ' + filepath)
                        if root_node != None:
                            root_tag = root_node.tag
                            if self.checkRootNodeTag(root_tag):
                                id_value = root_node[Common.ID_NODE_INDEX]
                                id_name = id_value.text
                                if root_tag.find(
                                        Common.DOMAIN_METADATA_TAG
                                ) >= 0 and id_name == domain_id:
                                    log.info('Processing domain: ' + id_name)
                                    domain_schemafile = self.findDomainSchemaFile(
                                        metadata_filename=filepath, log=log)
                                    if domain_schemafile is not None:
                                        self.domainAction.removeOrRenameField(
                                            filename=domain_schemafile,
                                            fieldname=fieldname,
                                            newfieldname=newfieldname,
                                            newdbcolname=newdbcolname,
                                            log=log)
                                elif root_tag.find(
                                        Common.ADHOC_TOPIC_TAG) >= 0:
                                    log.info('Processing Ad Hoc Topic: ' +
                                             id_name)
                                    self.findAdhocTopicFiles(
                                        metadata_filename=filepath,
                                        adhoc_topic_id=id_name,
                                        log=log)
                                elif root_tag.find(Common.ADHOC_VIEW_TAG) >= 0:
                                    log.info('Processing Ad Hoc View: ' +
                                             id_name)
                                    if self.findAdhocViewFiles(
                                            metadata_filename=filepath,
                                            adhoc_view_id=id_name,
                                            log=log):
                                        self.adhocAction.removeRenameInputControlInMetadataFile(
                                            metadata_filename=filepath,
                                            fieldname=fieldname,
                                            newfieldname=newfieldname,
                                            log=log)
                                elif root_tag.find(Common.REPORT_TAG) >= 0:
                                    log.info('Processing Report: ' + id_name)
                                    if self.findReportFiles(
                                            metadata_filename=filepath,
                                            report_id=id_name,
                                            log=log):
                                        # check metadata for input control(s) if report is static
                                        self.reportAction.removeRenameInputControlInMetadataFile(
                                            metadata_filename=filepath,
                                            fieldname=fieldname,
                                            log=log)
        self.processFiles(fieldname, newfieldname, log)

    def processFiles(self, fieldname, newfieldname, log):
        for files in self.adhoc_topic_files_list:
            self.adhocAction.removeRenameField(files[0], files[1], fieldname,
                                               newfieldname, log)
        for files in self.adhoc_view_files_list:
            self.adhocAction.removeRenameField(files[0], files[1], fieldname,
                                               newfieldname, log)
        for files in self.report_list:
            self.reportAction.removeRenameField(files[0], files[1], fieldname,
                                                newfieldname, log)
コード例 #6
0
 def setUp(self):
     self.common = Common()
     self.log = self.common.configureLogging()
     self.test_datasource_name = 'test_domain'
コード例 #7
0
class CommonTest(unittest.TestCase):
    def setUp(self):
        self.common = Common()
        self.log = self.common.configureLogging()
        self.test_datasource_name = 'test_domain'

    def tearDown(self):
        pass

    def testRemoveDeclarationNode(self):
        some_tag_xml = '<someTag/>'
        xml_declaration = '<?xml version="1.0" encoding="UTF-8"?>'
        report_xml = xml_declaration + '\n' + some_tag_xml
        report_tuple = self.common.removeDeclarationNode(report_xml)
        self.assertEqual(xml_declaration + '\n', report_tuple[0],
                         'xml declaration does not match')
        self.assertEqual(some_tag_xml, report_tuple[1],
                         'xml body does not match')

    def testRemoveDeclarationNodeNoDeclarationNode(self):
        some_tag_xml = '<someTag/>'
        report_xml = some_tag_xml
        report_tuple = self.common.removeDeclarationNode(report_xml)
        self.assertEqual('', report_tuple[0],
                         'xml declaration should be empty')
        self.assertEqual(some_tag_xml, report_tuple[1],
                         'xml body does not match')

    def testFixVisibleLevels(self):
        fieldname = 'name1'
        newfieldname = 'name2'
        mock_root = MagicMock(name='mock_root')
        mock_node1 = MagicMock(name='mock_node1')
        mock_node1_text = PropertyMock(return_value=fieldname)
        type(mock_node1).text = mock_node1_text
        mock_root.xpath = MagicMock(side_effect=[[mock_node1]])
        self.common.fixVisibleLevels(root=mock_root,
                                     fieldname=fieldname,
                                     newfieldname=newfieldname,
                                     log=self.log)
        mock_node1_text.assert_called_with(newfieldname)

    def testFixVisibleLevelsDoesNotMatch(self):
        fieldname = 'name1'
        newfieldname = 'name2'
        mock_root = MagicMock(name='mock_root')
        mock_node1 = MagicMock(name='mock_node1')
        mock_node1_text = PropertyMock(return_value='something else')
        type(mock_node1).text = mock_node1_text
        mock_root.xpath = MagicMock(side_effect=[[mock_node1]])
        self.common.fixVisibleLevels(root=mock_root,
                                     fieldname=fieldname,
                                     newfieldname=newfieldname,
                                     log=self.log)
        mock_node1_text.assert_called_once_with()

    def testFixVisibleLevelsIsRemove(self):
        fieldname = 'name1'
        mock_root = MagicMock(name='mock_root')
        self.common.fixVisibleLevels(root=mock_root,
                                     fieldname=fieldname,
                                     newfieldname=None,
                                     log=self.log)
        mock_root.assert_not_called()
コード例 #8
0
class ReportAction():

    common = Common()

    def removeRenameParameter(self, root, fieldname, newfieldname, log):
        for param in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + Common.PARAMETER,
                                namespaces=Common.JRXML_NAMESPACE):
            paramName = param.get(Common.NAME)
            if paramName.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming parameter ' + paramName + ' to ' +
                              paramName.replace(fieldname, newfieldname))
                    param.attrib[Common.NAME] = paramName.replace(
                        fieldname, newfieldname)
                    for child in param:
                        if child.tag.find('parameterDescription') >= 0:
                            childtext = child.text
                            if childtext.find(fieldname) >= 0:
                                log.debug(
                                    'changing parameter description to: ' +
                                    childtext.replace(fieldname, newfieldname))
                                child.text = etree.CDATA(
                                    childtext.replace(fieldname, newfieldname))
                else:
                    log.debug('removing parameter: ' + paramName)
                    param.getparent().remove(param)

    def removeRenameFieldInFieldList(self, root, fieldname, newfieldname, log):
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + Common.FIELD,
                                namespaces=Common.JRXML_NAMESPACE):
            fieldName = field.get(Common.NAME)
            if fieldName.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming field ' + fieldName + ' to ' +
                              fieldName.replace(fieldname, newfieldname))
                    field.attrib[Common.NAME] = fieldName.replace(
                        fieldname, newfieldname)
                    # rename associated level property
                    for child in field:
                        childvalue = child.get(Common.VALUE)
                        if childvalue is not None and childvalue.find(
                                fieldname) >= 0:
                            log.debug(
                                'renaming field level property to ' +
                                childvalue.replace(fieldname, newfieldname))
                            child.attrib[Common.VALUE] = childvalue.replace(
                                fieldname, newfieldname)
                        elif child.tag.find('fieldDescription') >= 0:
                            childtext = child.text
                            if childtext is not None and childtext.find(
                                    fieldname) >= 0:
                                log.debug(
                                    'changing field description to ' +
                                    childtext.replace(fieldname, newfieldname))
                                child.text = etree.CDATA(
                                    childtext.replace(fieldname, newfieldname))
                else:
                    log.debug('removing field: ' + fieldName)
                    field.getparent().remove(field)

    def removeRenameQueryFieldInReportQuery(self, root, fieldname,
                                            newfieldname, log):
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.QUERY_FIELD):
            fieldID = field.get(Common.ID)
            if fieldID.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming query field ' + fieldID + ' to ' +
                              fieldID.replace(fieldname, newfieldname))
                    field.attrib[Common.ID] = fieldID.replace(
                        fieldname, newfieldname)
                else:
                    log.debug('removing field from query: ' + fieldID)
                    field.getparent().remove(field)
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                'queryFilterString'):
            filterString = field.text
            if filterString.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('changing query filter string to ' +
                              filterString.replace(fieldname, newfieldname))
                    field.text = filterString.replace(fieldname, newfieldname)
                else:
                    # Break up the filter into parts separated by AND and OR
                    filterList = re.split('AND |OR ', filterString)
                    for clause in filterList:
                        if clause.find(fieldname) >= 0:
                            filterString = filterString.replace(clause, '')
                            # Fix this kludgy mess
                            filterString = filterString.replace(
                                'AND AND', 'AND')
                            filterString = filterString.replace('AND OR', 'OR')
                            filterString = filterString.replace(
                                'OR AND', 'AND')
                            filterString = filterString.replace('OR OR', 'OR')
                            filterString = filterString.strip()
                            if filterString.startswith(
                                    'AND') or filterString.endswith('AND'):
                                filterString = filterString.replace(
                                    'AND', '').strip()
                            elif filterString.startswith(
                                    'OR') or filterString.endswith('OR'):
                                filterString = filterString.replace(
                                    'OR', '').strip()
                            log.debug('modified query filter string: ' +
                                      filterString)
                            field.text = filterString
                    if filterString is None or filterString == '':
                        field.getparent().remove(field)

    def reinsertQueryIntoReport(self, root, query_str):
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.QUERY_STRING,
                                namespaces=Common.JRXML_NAMESPACE):
            field.text = etree.CDATA(query_str)
        return query_str

    def removeRenameDetailFieldInTable(self, root, fieldname, newfieldname,
                                       log):
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.TEXTFIELD_EXPR_TAG,
                                namespaces=Common.JRXML_NAMESPACE):
            fieldText = field.text
            if fieldText.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming detail field ' + fieldText + ' to ' +
                              fieldText.replace(fieldname, newfieldname))
                    field.text = etree.CDATA(
                        fieldText.replace(fieldname, newfieldname))
                    # Fix the patternExpression node text if there is one
                    sibling = field.getnext()
                    if sibling is not None and sibling.tag.find(
                            'patternExpression') >= 0:
                        siblingText = sibling.text
                        if siblingText is not None and siblingText.find(
                                fieldname) >= 0:
                            log.debug(
                                'renaming field name in pattern expression to '
                                + siblingText.replace(fieldname, newfieldname))
                            sibling.text = etree.CDATA(
                                siblingText.replace(fieldname, newfieldname))
                else:
                    log.debug('removing detail field: ' + fieldText)
                    ggparentfield = field.getparent().getparent().getparent()
                    # subtract field width from parent
                    field_width_str = ggparentfield.get(Common.WIDTH)
                    if field_width_str != None:
                        # This report was created from an Ad Hoc view
                        field_width = int(field_width_str)
                        gggparentfield = ggparentfield.getparent()
                        gggparentfield.attrib[Common.WIDTH] = str(
                            int(gggparentfield.get(Common.WIDTH)) -
                            field_width)
                        gggparentfield.remove(ggparentfield)
                        # Fix the width in the reportElement in the header
                        for reportGroupField in root.xpath(
                                Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + 'n:reportElement',
                                namespaces=Common.JRXML_NAMESPACE):
                            reportGroupGGParent = reportGroupField.getparent(
                            ).getparent().getparent()
                            if reportGroupGGParent.tag.find(
                                    'groupHeader') >= 0:
                                reportGroupField.attrib[
                                    Common.WIDTH] = gggparentfield.get(
                                        Common.WIDTH)
                    else:
                        # This is a static report created using Jaspersoft Studio
                        parent = field.getparent()
                        parent.getparent().remove(parent)

    def removeRenameFieldInGroup(self, root, fieldname, newfieldname, log):
        for group in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + Common.GROUP,
                                namespaces=Common.JRXML_NAMESPACE):
            fieldName = group.get(Common.NAME)
            if fieldName.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming group ' + fieldName + ' to ' +
                              fieldName.replace(fieldname, newfieldname))
                    group.attrib[Common.NAME] = fieldName.replace(
                        fieldname, newfieldname)
                    # change groupExpression
                    groupExpression = group[0].text
                    if groupExpression.find(fieldname) >= 0:
                        log.debug(
                            'changing groupExpression ' + groupExpression +
                            ' to ' +
                            groupExpression.replace(fieldname, newfieldname))
                        group[0].text = etree.CDATA(
                            groupExpression.replace(fieldname, newfieldname))
                else:
                    log.debug('removing group: ' + fieldName)
                    group.getparent().remove(group)
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.CGROUPHEADER,
                                namespaces=Common.JRXML_COMPONENTS_NAMESPACE):
            fieldGroupName = field.get(Common.GROUPNAME)
            if fieldGroupName.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming column group ' + fieldGroupName +
                              ' to ' +
                              fieldGroupName.replace(fieldname, newfieldname))
                    field.attrib[Common.GROUPNAME] = fieldGroupName.replace(
                        fieldname, newfieldname)
                else:
                    log.debug('removing column group: ' + fieldGroupName)
                    field.getparent().remove(field)

    def insertDummyRowGroup(self, root, log):
        # Inserting dummy row group
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                'n:crosstabDataset',
                                namespaces=Common.JRXML_NAMESPACE):
            parent = field.getparent()
            parser = etree.XMLParser(strip_cdata=False)
            dummy_row_group_xml = etree.fromstring(Common.DUMMY_ROW_GROUP,
                                                   parser)
            log.debug('inserting dummy row group at position: ' +
                      str(parent.index(field) + 1))
            parent.insert(parent.index(field) + 1, dummy_row_group_xml)
        # Removing crosstab header node
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                'n:crosstabHeader',
                                namespaces=Common.JRXML_NAMESPACE):
            log.debug('removing crosstabHeader node')
            field.getparent().remove(field)

    def removeRenameRowGroupInCrosstab(self, root, fieldname, newfieldname,
                                       log):
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + Common.ROWGROUP,
                                namespaces=Common.JRXML_NAMESPACE):
            fieldName = field.get(Common.NAME)
            if fieldName.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming row group ' + fieldName + ' to ' +
                              fieldName.replace(fieldname, newfieldname))
                    field.attrib[Common.NAME] = fieldName.replace(
                        fieldname, newfieldname)
                    self.fixGroupChildNodes(field=field,
                                            fieldname=fieldname,
                                            newfieldname=newfieldname,
                                            log=log)
                else:
                    log.debug('removing row group: ' + fieldName)
                    field.getparent().remove(field)
                    # fix row group count
                    for param in root.xpath(
                            Common.REPO_PATH_SEPARATOR +
                            Common.REPO_PATH_SEPARATOR +
                            'n:crosstabParameter[@name="CrosstabRowGroupsCount"]',
                            namespaces=Common.JRXML_NAMESPACE):
                        rowGroupText = param[Common.STATE_FILE_NODE_INDEX].text
                        rowGroupCount = int(
                            rowGroupText[rowGroupText.find('(') +
                                         1:rowGroupText.find(')')]) - 1
                        if rowGroupCount == 0:
                            self.insertDummyRowGroup(root=root, log=log)
                        else:
                            param[Common.
                                  STATE_FILE_NODE_INDEX].text = etree.CDATA(
                                      'new Integer(' + str(rowGroupCount) +
                                      ')')

    def removeRenameColumnGroupInCrosstab(self, root, fieldname, newfieldname,
                                          log):
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.COLUMNGROUP,
                                namespaces=Common.JRXML_NAMESPACE):
            fieldName = field.get(Common.NAME)
            if fieldName.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming column group ' + fieldName + ' to ' +
                              fieldName.replace(fieldname, newfieldname))
                    field.attrib[Common.NAME] = fieldName.replace(
                        fieldname, newfieldname)
                    self.fixGroupChildNodes(field=field,
                                            fieldname=fieldname,
                                            newfieldname=newfieldname,
                                            log=log)
                else:
                    log.debug('removing column group: ' + fieldName)
                    field.getparent().remove(field)
                    # fix column group count
                    for param in root.xpath(
                            Common.REPO_PATH_SEPARATOR +
                            Common.REPO_PATH_SEPARATOR +
                            'n:crosstabParameter[@name="CrosstabColumnGroupsCount"]',
                            namespaces=Common.JRXML_NAMESPACE):
                        rowGroupText = param[Common.STATE_FILE_NODE_INDEX].text
                        rowGroupCount = int(
                            rowGroupText[rowGroupText.find('(') +
                                         1:rowGroupText.find(')')]) - 1
                        param[Common.STATE_FILE_NODE_INDEX].text = etree.CDATA(
                            'new Integer(' + str(rowGroupCount) + ')')

    def fixGroupChildNodes(self, field, fieldname, newfieldname, log):
        # Fix bucket expression
        for bucket in field.xpath(Common.REPO_PATH_SEPARATOR +
                                  Common.REPO_PATH_SEPARATOR +
                                  'n:bucketExpression',
                                  namespaces=Common.JRXML_NAMESPACE):
            bucketText = bucket.text
            if bucketText.find(fieldname) >= 0:
                log.debug('changing bucketExpression to: ' +
                          bucketText.replace(fieldname, newfieldname))
                bucket.text = etree.CDATA(
                    bucketText.replace(fieldname, newfieldname))
        # fix hyperlinkTooltipExpression
        for tooltipExpr in field.xpath(Common.REPO_PATH_SEPARATOR +
                                       Common.REPO_PATH_SEPARATOR +
                                       'n:hyperlinkTooltipExpression',
                                       namespaces=Common.JRXML_NAMESPACE):
            textFieldExprText = tooltipExpr.text
            if textFieldExprText.find(fieldname) >= 0:
                log.debug('changing hyperlinkTooltipExpression to: ' +
                          textFieldExprText.replace(fieldname, newfieldname))
                tooltipExpr.text = etree.CDATA(
                    textFieldExprText.replace(fieldname, newfieldname))
        # fix reportElement style
        for reportElementExpr in field.xpath(
                Common.REPO_PATH_SEPARATOR + Common.REPO_PATH_SEPARATOR +
                'n:reportElement',
                namespaces=Common.JRXML_NAMESPACE):
            reportElementExprStyle = reportElementExpr.get(Common.STYLE_TAG)
            if reportElementExprStyle.find(fieldname) >= 0:
                log.debug(
                    'changing reportElement style to: ' +
                    reportElementExprStyle.replace(fieldname, newfieldname))
                reportElementExpr.attrib[
                    Common.STYLE_TAG] = reportElementExprStyle.replace(
                        fieldname, newfieldname)

    def removeRenameFieldInMeasureExpression(self, exprText, fieldname,
                                             newfieldname, log):
        if exprText.find(fieldname) >= 0:
            if newfieldname is not None and newfieldname != '_':
                log.debug('renaming field in measure expression to' +
                          exprText.replace(fieldname, newfieldname))
                exprText = exprText.replace(fieldname, newfieldname)
            else:
                log.debug('removing field ' + fieldname +
                          'from measureExpression: ' + exprText)
                exprText = exprText.replace(
                    '$F{' + fieldname + '__DISCRIMINATOR}', '')
                if exprText.find('||  ||') >= 0:
                    exprText = exprText.replace('||  ||', '||')
                elif exprText.endswith(' || '):
                    exprText = self.rreplace(exprText, ' || ', '')
        return exprText

    def removeRenameFieldInMeasureExpressionWrapper(self, root, fieldname,
                                                    newfieldname, log):
        for expr in root.xpath(Common.REPO_PATH_SEPARATOR +
                               Common.REPO_PATH_SEPARATOR +
                               'n:measureExpression',
                               namespaces=Common.JRXML_NAMESPACE):
            expr.text = etree.CDATA(
                self.removeRenameFieldInMeasureExpression(
                    exprText=expr.text,
                    fieldname=fieldname,
                    newfieldname=newfieldname,
                    log=log))

    def fixConditionalStyleExpression(self, root, fieldname, newfieldname,
                                      log):
        for expr in root.xpath(Common.REPO_PATH_SEPARATOR +
                               Common.REPO_PATH_SEPARATOR +
                               'n:conditionExpression',
                               namespaces=Common.JRXML_NAMESPACE):
            exprText = expr.text
            if exprText.find(fieldname) >= 0:
                grandparent = expr.getparent().getparent()
                if grandparent.tag.find(Common.STYLE_TAG) >= 0:
                    grandparentName = grandparent.get(Common.NAME)
                    if grandparentName.find(fieldname) >= 0:
                        if newfieldname is not None and newfieldname != '_':
                            log.debug(
                                'changing conditional style expression to: ' +
                                exprText.replace(fieldname, newfieldname))
                            expr.text = etree.CDATA(
                                exprText.replace(fieldname, newfieldname))
                            log.debug('changing style name to: ' +
                                      grandparentName.replace(
                                          fieldname, newfieldname))
                            grandparent.attrib[
                                Common.NAME] = grandparentName.replace(
                                    fieldname, newfieldname)
                        else:
                            log.debug('removing style: ' + grandparentName)
                            grandparent.getparent().remove(grandparent)
        # check parent style
        for style in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + 'n:' +
                                Common.STYLE_TAG,
                                namespaces=Common.JRXML_NAMESPACE):
            parentStyle = style.get(Common.STYLE_TAG)
            if parentStyle is not None and parentStyle.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('changing parent style name to: ' +
                              parentStyle.replace(fieldname, newfieldname))
                    style.attrib[Common.STYLE_TAG] = parentStyle.replace(
                        fieldname, newfieldname)
                else:
                    log.debug('removing style ' + style.get(Common.NAME) +
                              ' with parent style: ' + parentStyle)
                    style.getparent().remove(style)

    def removeRenameFieldInJRXML(self, root, fieldname, newfieldname, log):
        self.removeRenameParameter(root=root,
                                   fieldname=fieldname,
                                   newfieldname=newfieldname,
                                   log=log)
        self.removeRenameFieldInFieldList(root=root,
                                          fieldname=fieldname,
                                          newfieldname=newfieldname,
                                          log=log)
        self.removeRenameDetailFieldInTable(root=root,
                                            fieldname=fieldname,
                                            newfieldname=newfieldname,
                                            log=log)
        self.removeRenameFieldInGroup(root=root,
                                      fieldname=fieldname,
                                      newfieldname=newfieldname,
                                      log=log)
        self.removeRenameRowGroupInCrosstab(root=root,
                                            fieldname=fieldname,
                                            newfieldname=newfieldname,
                                            log=log)
        self.removeRenameColumnGroupInCrosstab(root=root,
                                               fieldname=fieldname,
                                               newfieldname=newfieldname,
                                               log=log)
        self.removeRenameFieldInMeasureExpressionWrapper(
            root=root, fieldname=fieldname, newfieldname=newfieldname, log=log)
        self.fixConditionalStyleExpression(root=root,
                                           fieldname=fieldname,
                                           newfieldname=newfieldname,
                                           log=log)

    def removeRenameFieldInJRXMLFile(self, jrxml_filename, fieldname,
                                     newfieldname, log):
        if jrxml_filename.find(Common.PROPERTIES_EXT) == -1:
            log.debug('Preparing to remove field(s) from JRXML file: ' +
                      jrxml_filename[jrxml_filename.
                                     rfind(Common.REPO_PATH_SEPARATOR) + 1:])
            with open(jrxml_filename, 'r', encoding='utf-8') as h:
                report_xml = h.read()
            report_tuple = self.common.removeDeclarationNode(
                xml_string=report_xml)
            report_xml = report_tuple[1]
            parser = etree.XMLParser(strip_cdata=False)
            # remove queryString node that contains an extra XML declaration to avoid syntax error
            try:
                begin_index = report_xml.index('<' + Common.QUERY + '>')
            except ValueError:
                log.debug(
                    'Report does not contain a domain query.  Skipping...')
                begin_index = -1
            if begin_index > 0:
                end_index = report_xml.find(']]>', begin_index)
                report_xml_outer = report_xml[0:begin_index] + report_xml[
                    end_index:len(report_xml)]
                report_xml_inner = report_xml[begin_index:end_index]
                report_root = etree.fromstring(report_xml_outer, parser)
                self.removeRenameFieldInJRXML(root=report_root,
                                              fieldname=fieldname,
                                              newfieldname=newfieldname,
                                              log=log)
                query_root = etree.fromstring(report_xml_inner)
                self.removeRenameQueryFieldInReportQuery(
                    root=query_root,
                    fieldname=fieldname,
                    newfieldname=newfieldname,
                    log=log)
                # re-insert domain query back into topic
                query_bytea = etree.tostring(query_root,
                                             pretty_print=True,
                                             encoding='UTF-8')
                query_str = "".join(map(chr, query_bytea))
                self.reinsertQueryIntoReport(root=report_root,
                                             query_str=query_str)
            else:
                report_root = etree.fromstring(report_xml, parser)
                self.removeRenameFieldInJRXML(root=report_root,
                                              fieldname=fieldname,
                                              newfieldname=newfieldname,
                                              log=log)
            report_bytea = etree.tostring(report_root,
                                          pretty_print=True,
                                          encoding='UTF-8')
            report_xml = "".join(map(chr, report_bytea))
            # re-insert original XML declaration
            report_xml = report_tuple[0] + report_xml
            with open(jrxml_filename, 'w', encoding='utf-8') as h:
                h.write(report_xml)

    def removeRenameFieldInState(self, root, fieldname, newfieldname, log):
        # if the field is a measure
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR + Common.MEASURE):
            fieldFieldName = field.get(Common.FIELD_NAME)
            if fieldFieldName != None and fieldFieldName.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming measure fieldName attribute ' +
                              fieldFieldName + ' to ' +
                              fieldFieldName.replace(fieldname, newfieldname))
                    field.attrib[Common.FIELD_NAME] = fieldFieldName.replace(
                        fieldname, newfieldname)
                    # check and rename the "name" attribute if necessary
                    fieldName = field.get(Common.NAME)
                    if fieldName is not None and fieldName.find(
                            fieldname) >= 0:
                        log.debug('renaming measure name attribute ' +
                                  fieldName + ' to ' +
                                  fieldName.replace(fieldname, newfieldname))
                        field.attrib[Common.NAME] = fieldName.replace(
                            fieldname, newfieldname)
                    # check and rename the labelOverride property if necessary
                    labelOverride = field.get(Common.LABEL_OVERRIDE)
                    if labelOverride is not None and labelOverride.find(
                            fieldname) >= 0:
                        log.debug(
                            'changing labelOverride property from ' +
                            labelOverride + ' to ' +
                            labelOverride.replace(fieldname, newfieldname))
                        field.attrib[
                            Common.LABEL_OVERRIDE] = labelOverride.replace(
                                fieldname, newfieldname)
                else:
                    log.debug('removing measure: ' + fieldFieldName)
                    field.getparent().remove(field)
        # if the field is a dimension
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.QUERY_DIMENSION):
            fieldFieldName = field.get(Common.FIELD_NAME)
            if fieldFieldName != None and fieldFieldName.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming dimension fieldName attribute ' +
                              fieldFieldName + ' to ' +
                              fieldFieldName.replace(fieldname, newfieldname))
                    field.attrib[Common.FIELD_NAME] = fieldFieldName.replace(
                        fieldname, newfieldname)
                    # check and rename the "name" attribute if necessary
                    fieldName = field.get(Common.NAME)
                    if fieldName is not None and fieldName.find(
                            fieldname) >= 0:
                        log.debug('renaming measure name attribute ' +
                                  fieldName + ' to ' +
                                  fieldName.replace(fieldname, newfieldname))
                        field.attrib[Common.NAME] = fieldName.replace(
                            fieldname, newfieldname)
                else:
                    log.debug('removing dimension: ' + fieldFieldName)
                    field.getparent().remove(field)
        # if the field is a subfilter
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.EXPRESSION_STRING):
            fieldText = field.text
            if fieldText.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming subfilter ' + fieldText + ' to ' +
                              fieldText.replace(fieldname, newfieldname))
                    field.text = fieldText.replace(fieldname, newfieldname)
                    # check and fix parameterizedExpressionString if necessary
                    sibling = field.getnext()
                    if sibling is not None and sibling.tag == 'parameterizedExpressionString':
                        siblingText = sibling.text
                        if siblingText is not None and siblingText.find(
                                fieldname) >= 0:
                            log.debug(
                                'renaming column(s) in parameterizedExpressionString to '
                                + siblingText.replace(fieldname, newfieldname))
                            sibling.text = siblingText.replace(
                                fieldname, newfieldname)
                else:
                    parent = field.getparent()
                    log.debug('removing subfilter: ' + parent.get(Common.ID))
                    parent.getparent().remove(parent)
        # fix visible levels
        self.common.fixVisibleLevels(root=root,
                                     fieldname=fieldname,
                                     newfieldname=newfieldname,
                                     log=log)

    def removeRenameFieldInStateFile(self, state_filename, fieldname,
                                     newfieldname, log):
        if state_filename is not None and state_filename.find(
                Common.PROPERTIES_EXT) == -1:
            log.debug('Preparing to remove field(s) from state file: ' +
                      state_filename[state_filename.
                                     rfind(Common.REPO_PATH_SEPARATOR) + 1:])
            with open(state_filename, 'r', encoding='utf-8') as h:
                try:
                    state_xml = h.read()
                except UnicodeDecodeError:
                    log.debug('Ignoring non-text file: ' + state_filename)
                    return
            state_tuple = self.common.removeDeclarationNode(
                xml_string=state_xml)
            state_root = etree.fromstring(state_tuple[1])
            self.removeRenameFieldInState(root=state_root,
                                          fieldname=fieldname,
                                          newfieldname=newfieldname,
                                          log=log)
            state_bytea = etree.tostring(state_root,
                                         pretty_print=True,
                                         encoding='UTF-8')
            state_xml = "".join(map(chr, state_bytea))
            # re-insert original XML declaration
            state_xml = state_tuple[0] + state_xml
            with open(state_filename, 'w', encoding='utf-8') as h:
                h.write(state_xml)

    def removeRenameField(self, state_filename, jrxml_filename, fieldname,
                          newfieldname, log):
        if isinstance(fieldname, list):
            if newfieldname is None:
                newfieldname = []
                for _ in fieldname:
                    newfieldname.append('_')
            for s1, s2 in zip(fieldname, newfieldname):
                self.removeRenameFieldInStateFile(
                    state_filename=state_filename,
                    fieldname=s1,
                    newfieldname=s2,
                    log=log)
                self.removeRenameFieldInJRXMLFile(
                    jrxml_filename=jrxml_filename,
                    fieldname=s1,
                    newfieldname=s2,
                    log=log)
        else:
            self.removeRenameFieldInStateFile(state_filename=state_filename,
                                              fieldname=fieldname,
                                              newfieldname=newfieldname,
                                              log=log)
            self.removeRenameFieldInJRXMLFile(jrxml_filename=jrxml_filename,
                                              fieldname=fieldname,
                                              newfieldname=newfieldname,
                                              log=log)

    def removeRenameInputControlInMetadata(self, root, fieldname, newfieldname,
                                           log):
        for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                Common.REPO_PATH_SEPARATOR +
                                Common.LOCAL_RESOURCE +
                                Common.REPO_PATH_SEPARATOR +
                                'queryValueColumn'):
            fieldText = field.text
            if fieldText.find(fieldname) >= 0:
                if newfieldname is not None and newfieldname != '_':
                    log.debug('renaming input control ' + fieldText + ' to ' +
                              fieldText.replace(fieldname, newfieldname))
                    field.text = fieldText.replace(fieldname, newfieldname)
                    # change the queryVisibleColumn field value
                    sibling = field.getprevious()
                    if sibling is not None and sibling.tag.find(
                            'queryVisibleColumn') >= 0:
                        siblingText = sibling.text
                        if siblingText.find(fieldname) >= 0:
                            log.debug(
                                'renaming queryVisibleColumn value ' +
                                siblingText + ' to ' +
                                siblingText.replace(fieldname, newfieldname))
                            sibling.text = siblingText.replace(
                                fieldname, newfieldname)
                    # replace any occurences in the query string
                    for query in root.xpath(Common.REPO_PATH_SEPARATOR +
                                            Common.REPO_PATH_SEPARATOR +
                                            Common.LOCAL_RESOURCE +
                                            Common.REPO_PATH_SEPARATOR +
                                            'queryString'):
                        queryText = query.text
                        if queryText.find(fieldname) >= 0:
                            log.debug('replacing all occurences of ' +
                                      fieldname + ' in query string with ' +
                                      newfieldname)
                            query.text = queryText.replace(
                                fieldname, newfieldname)
                    # change folder and name properties
                    for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                            Common.REPO_PATH_SEPARATOR +
                                            Common.LOCAL_RESOURCE +
                                            Common.REPO_PATH_SEPARATOR +
                                            'folder'):
                        fieldText = field.text
                        if fieldText.find(fieldname) >= 0:
                            log.debug(
                                'changing folder property from ' + fieldText +
                                ' to ' +
                                fieldText.replace(fieldname, newfieldname))
                            field.text = fieldText.replace(
                                fieldname, newfieldname)
                            sibling = field.getnext()
                            if sibling is not None and sibling.tag.find(
                                    Common.NAME) >= 0:
                                siblingText = sibling.text
                                if siblingText.find(fieldname) >= 0:
                                    log.debug('changing name property from ' +
                                              siblingText + ' to ' +
                                              siblingText.replace(
                                                  fieldname, newfieldname))
                                    sibling.text = siblingText.replace(
                                        fieldname, newfieldname)
                                # update the label if necessary
                                labelProp = sibling.getnext().getnext()
                                if labelProp is not None and labelProp.tag.find(
                                        Common.LABEL) >= 0:
                                    labelText = labelProp.text
                                    if labelText.find(fieldname) >= 0:
                                        log.debug(
                                            'changing label property from ' +
                                            labelText + ' to ' +
                                            labelText.replace(
                                                fieldname, newfieldname))
                                        labelProp.text = labelText.replace(
                                            fieldname, newfieldname)
                    # change any name properties we may have missed
                    for field in root.xpath(Common.REPO_PATH_SEPARATOR +
                                            Common.REPO_PATH_SEPARATOR +
                                            Common.LOCAL_RESOURCE +
                                            Common.REPO_PATH_SEPARATOR +
                                            Common.NAME):
                        fieldText = field.text
                        if fieldText.find(fieldname) >= 0:
                            log.debug(
                                'changing name property from ' + fieldText +
                                ' to ' +
                                fieldText.replace(fieldname, newfieldname))
                            field.text = fieldText.replace(
                                fieldname, newfieldname)
                else:
                    parent = field.getparent()
                    log.debug('removing input control: ' +
                              parent[Common.ID_NODE_INDEX].text)
                    parent.getparent().remove(parent)

    def removeRenameInputControlInMetadataFile(self, metadata_filename,
                                               fieldname, newfieldname, log):
        log.debug('Checking metadata file for input controls to remove: ' +
                  metadata_filename[metadata_filename.
                                    rfind(Common.REPO_PATH_SEPARATOR) + 1:])
        with open(metadata_filename) as h:
            metadata_xml = h.read()
        metadata_tuple = self.common.removeDeclarationNode(
            xml_string=metadata_xml)
        metadata_root = etree.fromstring(metadata_tuple[1])
        self.removeRenameInputControlInMetadata(root=metadata_root,
                                                fieldname=fieldname,
                                                newfieldname=newfieldname,
                                                log=log)
        metadata_bytea = etree.tostring(metadata_root,
                                        pretty_print=True,
                                        encoding='UTF-8')
        metadata_xml = "".join(map(chr, metadata_bytea))
        # re-insert original XML declaration
        metadata_xml = metadata_tuple[0] + metadata_xml
        if metadata_xml.endswith('\n'):
            metadata_xml = metadata_xml[0:len(metadata_xml) - 1]
        with open(metadata_filename, 'w') as h:
            h.write(metadata_xml)

    def rreplace(self, s, old, new):
        li = s.rsplit(old, 1)
        return new.join(li)
コード例 #9
0
class DomainActionTest(unittest.TestCase):

    common = Common()

    DOMAIN_SCHEMA = """<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.jaspersoft.com/2007/SL/XMLSchema" version="1.0">
  <dataSources>
  </dataSources>
  <items>
    <item description="name1" descriptionId="" id="name1" label="name1" labelId="" resourceId="JoinTree_1.table1.name1" />
    <item description="name2" descriptionId="" id="name2" label="name2" labelId="Something Else" resourceId="JoinTree_1.table2.name2" />
    <item description="name3" descriptionId="" id="name3" label="name3" labelId="" resourceId="JoinTree_1.table3.name3" />
  </items>
  <resources>
    <jdbcTable id="table1" datasourceId="SomeDataSourceJNDI" tableName="schema1.table1">
      <fieldList>
        <field id="table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
        <field id="name1" fieldDBName="name1" type="java.lang.String" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table2" datasourceId="SomeDataSourceJNDI" tableName="schema1.table2">
      <fieldList>
        <field id="table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
        <field id="name2" fieldDBName="name2" type="java.math.BigDecimal" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table3" datasourceId="SomeDataSourceJNDI" tableName="schema1.table3">
      <fieldList>
        <field id="table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="JoinTree_1" datasourceId="SomeDataSourceJNDI" tableName="schema1.fact_table1">
      <fieldList>
        <field id="public_table1.table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
        <field id="public_table1.name1" fieldDBName="name1" type="java.lang.String" />
        <field id="public_table2.table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
        <field id="public_table2.name2" fieldDBName="name2" type="java.math.BigDecimal" />
        <field id="public_table3.table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="public_table3.name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
      <joinInfo alias="public_fact_table1" referenceId="public_fact_table1" />
      <joinedDataSetList>
        <joinedDataSetRef>
          <joinString>join public_table1 public_table1 on (public_fact_table1.table1_id == public_table1.table1_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table2 public_table2 on (public_fact_table1.table2_id == public_table2.table2_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table3 public_table3 on (public_fact_table1.table3_id == public_table3.table3_id)</joinString>
        </joinedDataSetRef>
      </joinedDataSetList>
    </jdbcTable>
  </resources>
</schema>
"""
    DOMAIN_SCHEMA_WITHOUT_NAME1 = """<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.jaspersoft.com/2007/SL/XMLSchema" version="1.0">
  <dataSources>
  </dataSources>
  <items>
    <item description="name2" descriptionId="" id="name2" label="name2" labelId="Something Else" resourceId="JoinTree_1.table2.name2" />
    <item description="name3" descriptionId="" id="name3" label="name3" labelId="" resourceId="JoinTree_1.table3.name3" />
  </items>
  <resources>
    <jdbcTable id="table1" datasourceId="SomeDataSourceJNDI" tableName="schema1.table1">
      <fieldList>
        <field id="table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table2" datasourceId="SomeDataSourceJNDI" tableName="schema1.table2">
      <fieldList>
        <field id="table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
        <field id="name2" fieldDBName="name2" type="java.math.BigDecimal" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table3" datasourceId="SomeDataSourceJNDI" tableName="schema1.table3">
      <fieldList>
        <field id="table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="JoinTree_1" datasourceId="SomeDataSourceJNDI" tableName="schema1.fact_table1">
      <fieldList>
        <field id="public_table1.table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
        <field id="public_table2.table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
        <field id="public_table2.name2" fieldDBName="name2" type="java.math.BigDecimal" />
        <field id="public_table3.table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="public_table3.name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
      <joinInfo alias="public_fact_table1" referenceId="public_fact_table1" />
      <joinedDataSetList>
        <joinedDataSetRef>
          <joinString>join public_table1 public_table1 on (public_fact_table1.table1_id == public_table1.table1_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table2 public_table2 on (public_fact_table1.table2_id == public_table2.table2_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table3 public_table3 on (public_fact_table1.table3_id == public_table3.table3_id)</joinString>
        </joinedDataSetRef>
      </joinedDataSetList>
    </jdbcTable>
  </resources>
</schema>
"""
    DOMAIN_SCHEMA_WITHOUT_NAME1_OR_NAME2 = """<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.jaspersoft.com/2007/SL/XMLSchema" version="1.0">
  <dataSources>
  </dataSources>
  <items>
    <item description="name3" descriptionId="" id="name3" label="name3" labelId="" resourceId="JoinTree_1.table3.name3" />
  </items>
  <resources>
    <jdbcTable id="table1" datasourceId="SomeDataSourceJNDI" tableName="schema1.table1">
      <fieldList>
        <field id="table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table2" datasourceId="SomeDataSourceJNDI" tableName="schema1.table2">
      <fieldList>
        <field id="table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table3" datasourceId="SomeDataSourceJNDI" tableName="schema1.table3">
      <fieldList>
        <field id="table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="JoinTree_1" datasourceId="SomeDataSourceJNDI" tableName="schema1.fact_table1">
      <fieldList>
        <field id="public_table1.table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
        <field id="public_table2.table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
        <field id="public_table3.table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="public_table3.name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
      <joinInfo alias="public_fact_table1" referenceId="public_fact_table1" />
      <joinedDataSetList>
        <joinedDataSetRef>
          <joinString>join public_table1 public_table1 on (public_fact_table1.table1_id == public_table1.table1_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table2 public_table2 on (public_fact_table1.table2_id == public_table2.table2_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table3 public_table3 on (public_fact_table1.table3_id == public_table3.table3_id)</joinString>
        </joinedDataSetRef>
      </joinedDataSetList>
    </jdbcTable>
  </resources>
</schema>
"""
    DOMAIN_SCHEMA_RENAME_NAME1_TO_NAME4_RENAME_DB = """<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.jaspersoft.com/2007/SL/XMLSchema" version="1.0">
  <dataSources>
  </dataSources>
  <items>
    <item description="name1" descriptionId="" id="name4" label="name4" labelId="" resourceId="JoinTree_1.table1.name4" />
    <item description="name2" descriptionId="" id="name2" label="name2" labelId="Something Else" resourceId="JoinTree_1.table2.name2" />
    <item description="name3" descriptionId="" id="name3" label="name3" labelId="" resourceId="JoinTree_1.table3.name3" />
  </items>
  <resources>
    <jdbcTable id="table1" datasourceId="SomeDataSourceJNDI" tableName="schema1.table1">
      <fieldList>
        <field id="table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
        <field id="name4" fieldDBName="name4" type="java.lang.String" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table2" datasourceId="SomeDataSourceJNDI" tableName="schema1.table2">
      <fieldList>
        <field id="table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
        <field id="name2" fieldDBName="name2" type="java.math.BigDecimal" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table3" datasourceId="SomeDataSourceJNDI" tableName="schema1.table3">
      <fieldList>
        <field id="table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="JoinTree_1" datasourceId="SomeDataSourceJNDI" tableName="schema1.fact_table1">
      <fieldList>
        <field id="public_table1.table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
        <field id="public_table1.name4" fieldDBName="name4" type="java.lang.String" />
        <field id="public_table2.table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
        <field id="public_table2.name2" fieldDBName="name2" type="java.math.BigDecimal" />
        <field id="public_table3.table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="public_table3.name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
      <joinInfo alias="public_fact_table1" referenceId="public_fact_table1" />
      <joinedDataSetList>
        <joinedDataSetRef>
          <joinString>join public_table1 public_table1 on (public_fact_table1.table1_id == public_table1.table1_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table2 public_table2 on (public_fact_table1.table2_id == public_table2.table2_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table3 public_table3 on (public_fact_table1.table3_id == public_table3.table3_id)</joinString>
        </joinedDataSetRef>
      </joinedDataSetList>
    </jdbcTable>
  </resources>
</schema>
"""
    DOMAIN_SCHEMA_RENAME_NAME1_TO_NAME4_AND_NAME2_TO_NAME5 = """<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.jaspersoft.com/2007/SL/XMLSchema" version="1.0">
  <dataSources>
  </dataSources>
  <items>
    <item description="name1" descriptionId="" id="name4" label="name4" labelId="" resourceId="JoinTree_1.table1.name4" />
    <item description="name2" descriptionId="" id="name5" label="name2" labelId="Something Else" resourceId="JoinTree_1.table2.name5" />
    <item description="name3" descriptionId="" id="name3" label="name3" labelId="" resourceId="JoinTree_1.table3.name3" />
  </items>
  <resources>
    <jdbcTable id="table1" datasourceId="SomeDataSourceJNDI" tableName="schema1.table1">
      <fieldList>
        <field id="table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
        <field id="name4" fieldDBName="name1" type="java.lang.String" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table2" datasourceId="SomeDataSourceJNDI" tableName="schema1.table2">
      <fieldList>
        <field id="table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
        <field id="name5" fieldDBName="name2" type="java.math.BigDecimal" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table3" datasourceId="SomeDataSourceJNDI" tableName="schema1.table3">
      <fieldList>
        <field id="table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="JoinTree_1" datasourceId="SomeDataSourceJNDI" tableName="schema1.fact_table1">
      <fieldList>
        <field id="public_table1.table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
        <field id="public_table1.name4" fieldDBName="name1" type="java.lang.String" />
        <field id="public_table2.table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
        <field id="public_table2.name5" fieldDBName="name2" type="java.math.BigDecimal" />
        <field id="public_table3.table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="public_table3.name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
      <joinInfo alias="public_fact_table1" referenceId="public_fact_table1" />
      <joinedDataSetList>
        <joinedDataSetRef>
          <joinString>join public_table1 public_table1 on (public_fact_table1.table1_id == public_table1.table1_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table2 public_table2 on (public_fact_table1.table2_id == public_table2.table2_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table3 public_table3 on (public_fact_table1.table3_id == public_table3.table3_id)</joinString>
        </joinedDataSetRef>
      </joinedDataSetList>
    </jdbcTable>
  </resources>
</schema>
"""
    DOMAIN_SCHEMA_RENAME_NAME1_TO_NAME4_AND_NAME2_TO_NAME5_RENAME_DB = """<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.jaspersoft.com/2007/SL/XMLSchema" version="1.0">
  <dataSources>
  </dataSources>
  <items>
    <item description="name1" descriptionId="" id="name4" label="name4" labelId="" resourceId="JoinTree_1.table1.name4" />
    <item description="name2" descriptionId="" id="name5" label="name2" labelId="Something Else" resourceId="JoinTree_1.table2.name5" />
    <item description="name3" descriptionId="" id="name3" label="name3" labelId="" resourceId="JoinTree_1.table3.name3" />
  </items>
  <resources>
    <jdbcTable id="table1" datasourceId="SomeDataSourceJNDI" tableName="schema1.table1">
      <fieldList>
        <field id="table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
        <field id="name4" fieldDBName="name4" type="java.lang.String" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table2" datasourceId="SomeDataSourceJNDI" tableName="schema1.table2">
      <fieldList>
        <field id="table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
        <field id="name5" fieldDBName="name5" type="java.math.BigDecimal" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="table3" datasourceId="SomeDataSourceJNDI" tableName="schema1.table3">
      <fieldList>
        <field id="table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
    </jdbcTable>
    <jdbcTable id="JoinTree_1" datasourceId="SomeDataSourceJNDI" tableName="schema1.fact_table1">
      <fieldList>
        <field id="public_table1.table1_id" fieldDBName="table1_id" type="java.lang.Integer" />
        <field id="public_table1.name4" fieldDBName="name4" type="java.lang.String" />
        <field id="public_table2.table2_id" fieldDBName="table2_id" type="java.lang.Integer" />
        <field id="public_table2.name5" fieldDBName="name5" type="java.math.BigDecimal" />
        <field id="public_table3.table3_id" fieldDBName="table3_id" type="java.lang.Integer" />
        <field id="public_table3.name3" fieldDBName="name3" type="java.util.Date" />
      </fieldList>
      <joinInfo alias="public_fact_table1" referenceId="public_fact_table1" />
      <joinedDataSetList>
        <joinedDataSetRef>
          <joinString>join public_table1 public_table1 on (public_fact_table1.table1_id == public_table1.table1_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table2 public_table2 on (public_fact_table1.table2_id == public_table2.table2_id)</joinString>
        </joinedDataSetRef>
        <joinedDataSetRef>
          <joinString>join public_table3 public_table3 on (public_fact_table1.table3_id == public_table3.table3_id)</joinString>
        </joinedDataSetRef>
      </joinedDataSetList>
    </jdbcTable>
  </resources>
</schema>
"""
    fieldDBName = 'fieldDBName'

    def setUp(self):
        self.domain_action = DomainAction()
        self.log = self.common.configureLogging()
        self.curr_folder = '/tmp'
        self.test_domain_name = 'test_domain'
        files_path = Common.REPO_PATH_SEPARATOR + self.test_domain_name + '_files'
        self.schema_filepath = self.curr_folder + files_path + Common.REPO_PATH_SEPARATOR + 'schema.data'
        directory = os.path.dirname(self.schema_filepath)
        if not os.path.exists(directory):
            os.makedirs(directory)
        with open(self.schema_filepath, 'w') as h1:
            h1.write(self.DOMAIN_SCHEMA)

    def tearDown(self):
        try:
            os.remove(self.schema_filepath)
        except OSError:
            pass

    def testRemoveFieldFromSchemaIsFK(self):
        mock_root = MagicMock(name='mock_root')
        mock_node1 = MagicMock(name='mock_node1')
        mock_node1.text.find.return_value = -1
        mock_node1.get.return_value = 'name1'
        mock_node2 = MagicMock(name='mock_node2')
        mock_node2.text.find.return_value = 14
        node_list = [mock_node1, mock_node2]
        mock_root.xpath = MagicMock(side_effect=[node_list, '', ''])
        try:
            self.domain_action.renameOrRemoveFieldFromSchema(root=mock_root,
                                                             fieldname='name2',
                                                             newfieldname=None,
                                                             newdbcolname=None,
                                                             log=self.log)
            raise ValueError('This method call should not have worked')
        except ValueError as e:
            self.assertEqual(
                'We will probably be able to handle removing key fields in the future, but for now it is not allowed',
                e.args[0], 'incorrect error message')

    def testRemoveFieldFromSchemaIsItem(self):
        mock_root = MagicMock(name='mock_root')
        mock_node1 = MagicMock(name='mock_node1')
        mock_node1.text.find.return_value = -1
        mock_node1.get.return_value = 'name1'
        mock_node2 = MagicMock(name='mock_node2')
        mock_node2.text.find.return_value = -1
        mock_node2.get.return_value = 'name2'
        mock_node2.getparent.return_value = mock_root
        node_list = [mock_node1, mock_node2]
        mock_root.xpath = MagicMock(side_effect=['', node_list, ''])
        self.domain_action.renameOrRemoveFieldFromSchema(root=mock_root,
                                                         fieldname='name2',
                                                         newfieldname=None,
                                                         newdbcolname=None,
                                                         log=self.log)
        mock_root.remove.assert_called_with(mock_node2)

    def testRemoveFieldFromSchemaIsField(self):
        mock_root = MagicMock(name='mock_root')
        mock_node1 = MagicMock(name='mock_node1')
        mock_node1.text.find.return_value = -1
        mock_node1.get.return_value = 'name1'
        mock_node2 = MagicMock(name='mock_node2')
        mock_node2.text.find.return_value = -1
        mock_node2.get.return_value = 'name2'
        mock_node2.getparent.return_value = mock_root
        node_list = [mock_node1, mock_node2]
        mock_root.xpath = MagicMock(side_effect=['', '', node_list])
        self.domain_action.renameOrRemoveFieldFromSchema(root=mock_root,
                                                         fieldname='name2',
                                                         newfieldname=None,
                                                         newdbcolname=None,
                                                         log=self.log)
        mock_root.remove.assert_called_with(mock_node2)

    def testRenameFieldInSchemaIsItem(self):
        mock_root = MagicMock(name='mock_root')
        mock_node1 = MagicMock(name='mock_node1')
        mock_node1.get.return_value = 'name1'
        mock_node2 = MagicMock(name='mock_node2')
        mock_node2.get.return_value = 'name2'
        node_list = [mock_node1, mock_node2]
        mock_root.xpath = MagicMock(side_effect=[[], node_list, []])
        self.domain_action.renameOrRemoveFieldFromSchema(root=mock_root,
                                                         fieldname='name2',
                                                         newfieldname='name4',
                                                         newdbcolname=None,
                                                         log=self.log)
        mock_node2.attrib.__setitem__.assert_called_with(
            Common.RESOURCE_ID, 'name4')

    def testRenameFieldInSchemaIsField(self):
        mock_root = MagicMock(name='mock_root')
        mock_node1 = MagicMock(name='mock_node1')
        mock_node1.get.return_value = 'name1'
        mock_node2 = MagicMock(name='mock_node2')
        mock_node2.get.return_value = 'name2'
        node_list = [mock_node1, mock_node2]
        mock_root.xpath = MagicMock(side_effect=[[], [], node_list])
        self.domain_action.renameOrRemoveFieldFromSchema(root=mock_root,
                                                         fieldname='name2',
                                                         newfieldname='name4',
                                                         newdbcolname=None,
                                                         log=self.log)
        mock_node2.attrib.__setitem__.assert_called_once_with(
            Common.ID, 'name4')

    def testRenameFieldInSchemaIsFieldWithDBCol(self):
        mock_root = MagicMock(name='mock_root')
        mock_node1 = MagicMock(name='mock_node1')
        mock_node1.get.return_value = 'name1'
        mock_node2 = MagicMock(name='mock_node2')
        mock_node2.get.return_value = 'name2'
        node_list = [mock_node1, mock_node2]
        mock_root.xpath = MagicMock(side_effect=[[], [], node_list])
        self.domain_action.renameOrRemoveFieldFromSchema(root=mock_root,
                                                         fieldname='name2',
                                                         newfieldname='name4',
                                                         newdbcolname='name4',
                                                         log=self.log)
        mock_node2.attrib.__setitem__.assert_called_with(
            Common.FIELD_DB_NAME, 'name4')

    def testRemoveField(self):
        field_name = 'name1'
        self.domain_action.removeOrRenameField(filename=self.schema_filepath,
                                               fieldname=field_name,
                                               newfieldname=None,
                                               newdbcolname=None,
                                               log=self.log)
        with open(self.schema_filepath) as h:
            schema_xml = h.read()
            self.assertEqual(self.DOMAIN_SCHEMA_WITHOUT_NAME1.replace(' ', ''),
                             schema_xml.replace(' ', ''),
                             'Domain schema file does not match expected')

    def testRemoveFieldIsKey(self):
        field_name = 'table1_id'
        try:
            self.domain_action.removeOrRenameField(
                filename=self.schema_filepath,
                fieldname=field_name,
                newfieldname=None,
                newdbcolname=None,
                log=self.log)
            raise ValueError('This method call should not have worked')
        except ValueError as e:
            self.assertEqual(
                'We will probably be able to handle removing key fields in the future, but for now it is not allowed',
                e.args[0], 'incorrect error message')

    def testRenameDBField(self):
        oldfieldname = 'name1'
        newfieldname = 'name4'
        self.domain_action.removeOrRenameField(filename=self.schema_filepath,
                                               fieldname=oldfieldname,
                                               newfieldname=newfieldname,
                                               newdbcolname=newfieldname,
                                               log=self.log)
        with open(self.schema_filepath) as h:
            schema_xml = h.read()
            self.assertEqual(
                self.DOMAIN_SCHEMA_RENAME_NAME1_TO_NAME4_RENAME_DB.replace(
                    ' ', ''), schema_xml.replace(' ', ''),
                'Domain schema file does not match expected')

    def testRemoveMultipleFields(self):
        field_name = ['name1', 'name2']
        self.domain_action.removeOrRenameField(filename=self.schema_filepath,
                                               fieldname=field_name,
                                               newfieldname=None,
                                               newdbcolname=None,
                                               log=self.log)
        with open(self.schema_filepath) as h:
            schema_xml = h.read()
            self.assertEqual(
                self.DOMAIN_SCHEMA_WITHOUT_NAME1_OR_NAME2.replace(' ', ''),
                schema_xml.replace(' ', ''),
                'Domain schema file does not match expected')

    def testRenameMultipleFields(self):
        oldfieldname = ['name1', 'name2']
        newfieldname = ['name4', 'name5']
        self.domain_action.removeOrRenameField(filename=self.schema_filepath,
                                               fieldname=oldfieldname,
                                               newfieldname=newfieldname,
                                               newdbcolname=None,
                                               log=self.log)
        with open(self.schema_filepath) as h:
            schema_xml = h.read()
            self.assertEqual(
                self.DOMAIN_SCHEMA_RENAME_NAME1_TO_NAME4_AND_NAME2_TO_NAME5.
                replace(' ', ''), schema_xml.replace(' ', ''),
                'Domain schema file does not match expected')

    def testRenameMultipleFieldsWithDB(self):
        oldfieldname = ['name1', 'name2']
        newfieldname = ['name4', 'name5']
        newdbcolname = ['name4', 'name5']
        self.domain_action.removeOrRenameField(filename=self.schema_filepath,
                                               fieldname=oldfieldname,
                                               newfieldname=newfieldname,
                                               newdbcolname=newdbcolname,
                                               log=self.log)
        with open(self.schema_filepath) as h:
            schema_xml = h.read()
            self.assertEqual(
                self.
                DOMAIN_SCHEMA_RENAME_NAME1_TO_NAME4_AND_NAME2_TO_NAME5_RENAME_DB
                .replace(' ', ''), schema_xml.replace(' ', ''),
                'Domain schema file does not match expected')