XlsImExporter { public static void importXls(final FileMatcher fileMatcher, final File xlsFile, final Charset propertyFileEncoding, final MissingKeyAction missingKeyAction) { Require.nonNull(fileMatcher); Require.nonNull(xlsFile); final ApronOptions apronOptions= ApronOptions.create() .with(propertyFileEncoding != null ? propertyFileEncoding : UTF_8) .with(missingKeyAction); final XlsFile xlsFileObject= new XlsFile(xlsFile); final Map<I18nBundleKey, Collection<Translation>> content= xlsFileObject.getContent(); final Map<String, Map<Language, RememberingPropertyFile>> bundleFileMapping= new LinkedHashMap<>(); content.entrySet().forEach((entry) -> { final I18nBundleKey bundleKey= entry.getKey(); final String bundleBasename= bundleKey.getBundleBaseName(); final String propertyKey= bundleKey.getKey(); final Collection<Translation> translations= entry.getValue(); for (final Translation translation : translations) { if (!bundleFileMapping.containsKey(bundleBasename)) { bundleFileMapping.put(bundleBasename, new LinkedHashMap<>()); } if (!bundleFileMapping.get(bundleBasename).containsKey(translation.getLang())) { final File fileForBundle= getFileForBundle(fileMatcher.getRoot().toFile(), bundleBasename, translation.getLang()); if (!fileMatcher.matches(fileForBundle.toPath())) { LOGGER.log(Level.DEBUG, "Skipping import to file {} since it does not match inclusion pattern", fileForBundle); continue; } final PropertyFile propertyFile= new PropertyFile(); bundleFileMapping.get(bundleBasename).put(translation.getLang(), new RememberingPropertyFile(fileForBundle, propertyFile)); } final RememberingPropertyFile rpf= bundleFileMapping.get(bundleBasename).get(translation.getLang()); if ((translation.getValue() != null && !translation.getValue().isEmpty()) || rpf.propertyFile.containsKey(propertyKey)) { rpf.propertyFile.setValue(propertyKey, translation.getValue()); } } }); bundleFileMapping.values().forEach((Map<Language, RememberingPropertyFile> langPropMap) -> { langPropMap.values().forEach((RememberingPropertyFile rpf) -> { if (rpf.propertyFile.propertiesSize()> 0) { rpf.propertyFile.saveTo(rpf.actualFile, apronOptions); } }); }); }  static void importXls(final FileMatcher fileMatcher,
                               final File xlsFile,
                               final Charset propertyFileEncoding,
                               final MissingKeyAction missingKeyAction); static void exportXls(final FileMatcher fileMatcher,
                               final Charset propertyFileEncoding,
                               final File xlsFile);  }
@Test public void testImportXls() throws IOException, URISyntaxException { final Path propertiesRootDirectory= this.tmpFolder.newFolder().toPath(); final FileMatcher fileMatcher= new FileMatcher(propertiesRootDirectory, new String[]{"**/*.properties"}, new String[]{""}); final File xlsFile= new File(Resources.getResource("i18n_expected.xlsx").toURI()); XlsImExporter.importXls(fileMatcher, xlsFile, UTF_8, MissingKeyAction.NOTHING); final Path[] writtenResourceBundleFiles = Files.list(propertiesRootDirectory.resolve("i18n")).toArray(Path[]::new); assertThat(writtenResourceBundleFiles).containsOnly( propertiesRootDirectory.resolve("i18n/messages.properties"), propertiesRootDirectory.resolve("i18n/messages_de.properties") ); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages.properties").toFile()) .hasSameContentAs(propertiesRootDirectory.resolve("i18n").resolve("messages.properties").toFile()); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages_de.properties").toFile()) .hasSameContentAs(propertiesRootDirectory.resolve("i18n").resolve("messages_de.properties").toFile()); }
@Test public void testImportXls_OnlySpecifiedIncluded() throws IOException, URISyntaxException { final Path propertiesRootDirectory= this.tmpFolder.newFolder().toPath(); final FileMatcher fileMatcher= new FileMatcher(propertiesRootDirectory, new String[]{"**/messages_de.properties"}, new String[]{""}); final File xlsFile= new File(Resources.getResource("i18n_expected.xlsx").toURI()); XlsImExporter.importXls(fileMatcher, xlsFile, UTF_8, MissingKeyAction.NOTHING); final Path[] writtenResourceBundleFiles = Files.list(propertiesRootDirectory.resolve("i18n")).toArray(Path[]::new); assertThat(writtenResourceBundleFiles).containsOnly( propertiesRootDirectory.resolve("i18n/messages_de.properties") ); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages_de.properties").toFile()) .hasSameContentAs(propertiesRootDirectory.resolve("i18n").resolve("messages_de.properties").toFile()); }
@Test public void testImportXls_WithoutSpecifiedExcluded() throws IOException, URISyntaxException { final Path propertiesRootDirectory= this.tmpFolder.newFolder().toPath(); final FileMatcher fileMatcher= new FileMatcher(propertiesRootDirectory, new String[]{"***_de.properties"}); final File xlsFile= new File(Resources.getResource("i18n_expected.xlsx").toURI()); XlsImExporter.importXls(fileMatcher, xlsFile, UTF_8, MissingKeyAction.NOTHING); final Path[] writtenResourceBundleFiles = Files.list(propertiesRootDirectory.resolve("i18n")).toArray(Path[]::new); assertThat(writtenResourceBundleFiles).containsOnly( propertiesRootDirectory.resolve("i18n/messages.properties") ); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages.properties").toFile()) .hasSameContentAs(propertiesRootDirectory.resolve("i18n").resolve("messages.properties").toFile()); }
@Test public void testImportXls_AddedLanguageColumn() throws IOException, URISyntaxException { final Path propertiesRootDirectory= this.tmpFolder.newFolder().toPath(); final FileMatcher fileMatcher= new FileMatcher(propertiesRootDirectory, new String[]{"**/*.properties"}, new String[]{""}); final File xlsFile= new File(Resources.getResource("i18n_added_fr.xlsx").toURI()); XlsImExporter.importXls(fileMatcher, xlsFile, UTF_8, MissingKeyAction.NOTHING); final Path[] writtenResourceBundleFiles = Files.list(propertiesRootDirectory.resolve("i18n")).toArray(Path[]::new); assertThat(writtenResourceBundleFiles).containsOnly( propertiesRootDirectory.resolve("i18n/messages.properties"), propertiesRootDirectory.resolve("i18n/messages_de.properties"), propertiesRootDirectory.resolve("i18n/messages_fr.properties") ); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages.properties").toFile()) .hasSameContentAs(propertiesRootDirectory.resolve("i18n").resolve("messages.properties").toFile()); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages_de.properties").toFile()) .hasSameContentAs(propertiesRootDirectory.resolve("i18n").resolve("messages_de.properties").toFile()); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages_fr.properties").toFile()) .hasContent("yes = Oui\nno = Non\n"); }
@Test public void testImportXls_MissingKeys_Delete() throws IOException, URISyntaxException { final Path propertiesRootDirectory= this.tmpFolder.getRoot().toPath(); final Set<File> resourceBundleFiles= ImmutableSet.of( copyResourceToTmp("i18n/messages.properties"), copyResourceToTmp("i18n/messages_de.properties")); final FileMatcher fileMatcher= this.createFileMatcher(propertiesRootDirectory, resourceBundleFiles); final File xlsFile= new File(Resources.getResource("i18n_line_deleted.xlsx").toURI()); XlsImExporter.importXls(fileMatcher, xlsFile, UTF_8, MissingKeyAction.DELETE); final Path[] writtenResourceBundleFiles = Files.list(propertiesRootDirectory.resolve("i18n")).toArray(Path[]::new); assertThat(writtenResourceBundleFiles).containsOnly( propertiesRootDirectory.resolve("i18n/messages.properties"), propertiesRootDirectory.resolve("i18n/messages_de.properties") ); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages.properties").toFile()) .hasContent("" + "cancel = Cancel\n" + "\n"); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages_de.properties").toFile()) .hasContent("" + "cancel = Abbrechen\n" + "\n"); }
@Test public void testImportXls_MissingKeys_CommentOut() throws IOException, URISyntaxException { final Path propertiesRootDirectory= this.tmpFolder.getRoot().toPath(); final Set<File> resourceBundleFiles= ImmutableSet.of( copyResourceToTmp("i18n/messages.properties"), copyResourceToTmp("i18n/messages_de.properties")); final FileMatcher fileMatcher= this.createFileMatcher(propertiesRootDirectory, resourceBundleFiles); final File xlsFile= new File(Resources.getResource("i18n_line_deleted.xlsx").toURI()); XlsImExporter.importXls(fileMatcher, xlsFile, UTF_8, MissingKeyAction.COMMENT); final Path[] writtenResourceBundleFiles = Files.list(propertiesRootDirectory.resolve("i18n")).toArray(Path[]::new); assertThat(writtenResourceBundleFiles).containsOnly( propertiesRootDirectory.resolve("i18n/messages.properties"), propertiesRootDirectory.resolve("i18n/messages_de.properties") ); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages.properties").toFile()) .hasContent("" + "#ok = OK\n" + "cancel = Cancel\n" + "\n"); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages_de.properties").toFile()) .hasContent("" + "#ok = OK\n" + "cancel = Abbrechen\n" + "\n"); }
@Test public void testImportXls_MissingKeys_DoNothing() throws IOException, URISyntaxException { final Path propertiesRootDirectory= this.tmpFolder.getRoot().toPath(); final Set<File> resourceBundleFiles= ImmutableSet.of( copyResourceToTmp("i18n/messages.properties"), copyResourceToTmp("i18n/messages_de.properties")); final FileMatcher fileMatcher= this.createFileMatcher(propertiesRootDirectory, resourceBundleFiles); final File xlsFile= new File(Resources.getResource("i18n_line_deleted.xlsx").toURI()); XlsImExporter.importXls(fileMatcher, xlsFile, UTF_8, MissingKeyAction.NOTHING); final Path[] writtenResourceBundleFiles = Files.list(propertiesRootDirectory.resolve("i18n")).toArray(Path[]::new); assertThat(writtenResourceBundleFiles).containsOnly( propertiesRootDirectory.resolve("i18n/messages.properties"), propertiesRootDirectory.resolve("i18n/messages_de.properties") ); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages.properties").toFile()) .hasContent("" + "ok = OK\n" + "cancel = Cancel\n" + "\n"); assertThat(propertiesRootDirectory.resolve("i18n").resolve("messages_de.properties").toFile()) .hasContent("" + "ok = OK\n" + "cancel = Abbrechen\n" + "\n"); }
@Test public void testImportXls_LibreOfficeBug() throws IOException, URISyntaxException { final Path propertiesRootDirectory= this.tmpFolder.newFolder().toPath(); final FileMatcher fileMatcher= new FileMatcher(propertiesRootDirectory, new String[]{"**/*.properties"}, new String[]{""}); final File xlsFile= new File(Resources.getResource("libreoffice_nullValues.xlsx").toURI()); XlsImExporter.importXls(fileMatcher, xlsFile, UTF_8, MissingKeyAction.NOTHING); final Path[] writtenResourceBundleFiles = Files.list(propertiesRootDirectory).toArray(Path[]::new); assertThat(writtenResourceBundleFiles).containsOnly( propertiesRootDirectory.resolve("buttons_nl.properties"), propertiesRootDirectory.resolve("buttons_de.properties"), propertiesRootDirectory.resolve("items_de.properties") ); final PropertyFile pfButtonsDe= PropertyFile.from(propertiesRootDirectory.resolve("buttons_de.properties").toFile()); assertThat(pfButtonsDe.keys()).containsOnly("btn.enter", "btn.cancel"); assertThat(pfButtonsDe.get("btn.enter")).isEqualTo("OK"); assertThat(pfButtonsDe.get("btn.cancel")).isEqualTo("Abbrechen"); final PropertyFile pfButtonsNl= PropertyFile.from(propertiesRootDirectory.resolve("buttons_nl.properties").toFile()); assertThat(pfButtonsNl.keys()).containsOnly("btn.enter", "btn.cancel"); assertThat(pfButtonsNl.get("btn.enter")).isEqualTo("Ok"); assertThat(pfButtonsNl.get("btn.cancel")).isEqualTo("Annuleren"); final PropertyFile pfItemDe= PropertyFile.from(propertiesRootDirectory.resolve("items_de.properties").toFile()); assertThat(pfItemDe.keys()).containsOnly(""); assertThat(pfItemDe.get("")).isEqualTo("ID"); }
@Test public void testImportXls_DoNotCreateEmptyBundleFiles() throws IOException, URISyntaxException { final Path propertiesRootDirectory= this.tmpFolder.newFolder().toPath(); final FileMatcher fileMatcher= new FileMatcher(propertiesRootDirectory, new String[]{"**/*.properties"}, new String[]{""}); final File xlsFile= new File(Resources.getResource("libreoffice_emptyStrings.xlsx").toURI()); XlsImExporter.importXls(fileMatcher, xlsFile, UTF_8, MissingKeyAction.NOTHING); final Path[] writtenResourceBundleFiles = Files.list(propertiesRootDirectory).toArray(Path[]::new); assertThat(writtenResourceBundleFiles).containsOnly( propertiesRootDirectory.resolve("buttons_nl.properties"), propertiesRootDirectory.resolve("buttons_de.properties"), propertiesRootDirectory.resolve("items_de.properties") ); final PropertyFile pfButtonsDe= PropertyFile.from(propertiesRootDirectory.resolve("buttons_de.properties").toFile()); assertThat(pfButtonsDe.keys()).containsOnly("btn.enter", "btn.cancel"); assertThat(pfButtonsDe.get("btn.enter")).isEqualTo("OK"); assertThat(pfButtonsDe.get("btn.cancel")).isEqualTo("Abbrechen"); final PropertyFile pfButtonsNl= PropertyFile.from(propertiesRootDirectory.resolve("buttons_nl.properties").toFile()); assertThat(pfButtonsNl.keys()).containsOnly("btn.enter", "btn.cancel"); assertThat(pfButtonsNl.get("btn.enter")).isEqualTo("Ok"); assertThat(pfButtonsNl.get("btn.cancel")).isEqualTo("Annuleren"); final PropertyFile pfItemDe= PropertyFile.from(propertiesRootDirectory.resolve("items_de.properties").toFile()); assertThat(pfItemDe.keys()).containsOnly(""); assertThat(pfItemDe.get("")).isEqualTo("ID"); }
@Test @Ignore(value = "This requires larger changes to importXls, as we need to read in the existing files first to compare") public void testImportXls_OnlyWriteEmptyValuesIfKeyAlreadyExists() throws IOException, URISyntaxException { final Path propertiesRootDirectory= this.tmpFolder.newFolder().toPath(); final FileMatcher fileMatcher= new FileMatcher(propertiesRootDirectory, new String[]{"**/*.properties"}, new String[]{""}); final File xlsFile= new File(Resources.getResource("libreoffice_emptyStrings.xlsx").toURI()); final Path buttons_fr= this.createFile(propertiesRootDirectory.resolve("buttons_fr.properties"), "btn.cancel = to be overwritten\n"); final Path butons_nl= this.createFile(propertiesRootDirectory.resolve("buttons_nl.properties"), "btn.cancel = to be overwritten\n"); final Path items_nl= this.createFile(propertiesRootDirectory.resolve("items_nl.properties"), " = to be overwritten\n"); XlsImExporter.importXls(fileMatcher, xlsFile, UTF_8, MissingKeyAction.NOTHING); final Path[] writtenResourceBundleFiles = Files.list(propertiesRootDirectory).toArray(Path[]::new); assertThat(writtenResourceBundleFiles).containsOnly( propertiesRootDirectory.resolve("buttons_nl.properties"), propertiesRootDirectory.resolve("buttons_de.properties"), propertiesRootDirectory.resolve("buttons_fr.properties"), propertiesRootDirectory.resolve("items_de.properties"), propertiesRootDirectory.resolve("items_nl.properties") ); final PropertyFile pfButtonsDe= PropertyFile.from(propertiesRootDirectory.resolve("buttons_de.properties").toFile()); assertThat(pfButtonsDe.keys()).containsOnly("btn.enter", "btn.cancel"); assertThat(pfButtonsDe.get("btn.enter")).isEqualTo("OK"); assertThat(pfButtonsDe.get("btn.cancel")).isEqualTo("Abbrechen"); final PropertyFile pfButtonsNl= PropertyFile.from(propertiesRootDirectory.resolve("buttons_nl.properties").toFile()); assertThat(pfButtonsNl.keys()).containsOnly("btn.enter", "btn.cancel"); assertThat(pfButtonsNl.get("btn.enter")).isEqualTo("Ok"); assertThat(pfButtonsNl.get("btn.cancel")).isEqualTo("Annuleren"); final PropertyFile pfButtonsFr= PropertyFile.from(propertiesRootDirectory.resolve("buttons_fr.properties").toFile()); assertThat(pfButtonsFr.keys()).containsOnly("btn.cancel"); assertThat(pfButtonsFr.keys()).doesNotContain("btn.ok"); assertThat(pfButtonsFr.get("btn.cancel")).isEqualTo(""); final PropertyFile pfItemDe= PropertyFile.from(propertiesRootDirectory.resolve("items_de.properties").toFile()); assertThat(pfItemDe.keys()).containsOnly(""); assertThat(pfItemDe.get("")).isEqualTo("ID"); final PropertyFile pfItemNl= PropertyFile.from(propertiesRootDirectory.resolve("items_nl.properties").toFile()); assertThat(pfItemNl.keys()).containsOnly(""); assertThat(pfItemNl.get("")).isEqualTo(""); final PropertyFile pfItemFr= PropertyFile.from(propertiesRootDirectory.resolve("items_fr.properties").toFile()); assertThat(pfItemFr.keys()).isEmpty(); }