### Question:
TagCreator extends ProcessDefinition implements Serializable { @SuppressWarnings({"squid:S3776", "squid:S1141"}) public void parseTags(ActionManager manager) throws Exception { manager.withResolver(rr -> { final XSSFWorkbook workbook = new XSSFWorkbook(excelFile); final XSSFSheet sheet = workbook.getSheetAt(0); final Iterator<Row> rows = sheet.rowIterator(); final String tagsRootPath = new TagRootResolver(rr).getTagsLocationPath(); if (tagsRootPath == null) { record(ReportRowSatus.FAILED_TO_PARSE, "Abandoning Tag parsing. Unable to determine AEM Tags root (/content/cq:tags vs /etc/tags). Please ensure the path exists and is accessible by the user running Tag Creator.", "N/A", "N/A"); return; } while(rows.hasNext()) { final Row row = rows.next(); final Iterator<Cell> cells = row.cellIterator(); int cellIndex = 0; String previousTagId = null; while (cells.hasNext()) { final Cell cell = cells.next(); final String cellValue = StringUtils.trimToNull(cell.getStringCellValue()); if (StringUtils.isBlank(cellValue)) { break; } TagDefinition tagDefinition = getTagDefinition(primary, cellIndex, cellValue, previousTagId, tagsRootPath); if (tagDefinition == null) { tagDefinition = getTagDefinition(fallback, cellIndex, cellValue, previousTagId, tagsRootPath); } if (tagDefinition == null) { log.warn("Could not find a Tag Data Converter that accepts value [ {} ]; skipping...", cellValue); record(ReportRowSatus.FAILED_TO_PARSE, cellValue, "", ""); break; } else { cellIndex++; previousTagId = tagDefinition.getId(); if (tagDefinitions.get(tagDefinition.getId()) == null) { tagDefinitions.put(tagDefinition.getId(), tagDefinition); } } } } log.info("Finished Parsing and collected [ {} ] tags for import.", tagDefinitions.size()); }); } TagCreator(Map<String, ResourceDefinitionBuilder> resourceDefinitionBuilders); @Override void init(); @Override void buildProcess(ProcessInstance instance, ResourceResolver rr); @SuppressWarnings({"squid:S3776", "squid:S1141"}) void parseTags(ActionManager manager); void importTags(ActionManager manager); @Override void storeReport(ProcessInstance instance, ResourceResolver rr); static final String NAME; @FormField(
            name = "Excel File",
            description = "Provide the .xlsx file that defines the tag taxonomy",
            component = FileUploadComponent.class,
            options = {"mimeTypes=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "required"}
    )
    transient InputStream excelFile; @FormField(
            name = "Primary Converter",
            description = "This will be used first and the Fallback will only be used if this fails to generate a valid Tag definition.",
            component = SelectComponent.EnumerationSelector.class,
            options = {"default=TITLE_AND_NODE_NAME", "required"}
    )
    public TagBuilder primary; @FormField(
            name = "Fallback Converter",
            description = "This is only invoked when the Primary cannot generate a valid Tag definition. If this can also not genreate a valid Tag definition then the row will be skipped.",
            component = SelectComponent.EnumerationSelector.class,
            options = {"default=LOWERCASE_WITH_DASHES", "required"}
    )
    public TagBuilder fallback; }### Answer:
@Test public void testParseAssetFolderDefinitions() throws Exception { tagCreator.parseTags(actionManager); final int expected = 6; assertEquals(expected, tagCreator.tagDefinitions.size()); }