MultiBundleCSVFilter extends MultiBundleResourceFilter { @Override public Map<String, LanguageBundle> parse(InputStream inStream, FilterOptions options) throws IOException, ResourceFilterException { Map<String, LanguageBundleBuilder> builders = new HashMap<String, LanguageBundleBuilder>(); CSVParser parser = CSVParser.parse(inStream, StandardCharsets.UTF_8, CSVFormat.RFC4180.withHeader("module", "key", "value").withSkipHeaderRecord(true)); for (CSVRecord record : parser) { String bundle = record.get(0); String key = record.get(1); String value = record.get(2); LanguageBundleBuilder bundleBuilder = builders.get(bundle); if (bundleBuilder == null) { bundleBuilder = new LanguageBundleBuilder(true); builders.put(bundle, bundleBuilder); } bundleBuilder.addResourceString(key, value); } Map<String, LanguageBundle> result = new TreeMap<String, LanguageBundle>(); for (Entry<String, LanguageBundleBuilder> bundleEntry : builders.entrySet()) { String bundleName = bundleEntry.getKey(); LanguageBundle bundleData = bundleEntry.getValue().build(); result.put(bundleName, bundleData); } return result; }  @Override Map<String, LanguageBundle> parse(InputStream inStream, FilterOptions options); @Override void write(OutputStream outStream, Map<String, LanguageBundle> languageBundles, FilterOptions options); @Override void merge(InputStream baseStream, OutputStream outStream, Map<String, LanguageBundle> languageBundles,
            FilterOptions options); static final String ID; static final Type TYPE; }
@Test public void testParse() { TestResourceStringData[] expectedFoods = { new TestResourceStringData("apple", "Apple", 1), new TestResourceStringData("orange", "Orange", 2) }; TestResourceStringData[] expectedGreetings = { new TestResourceStringData("msg_hello", "Hello", 1), new TestResourceStringData("msg_bye", "Bye", 2) }; Map<String, TestResourceStringData[]> expectedDataMap = new HashMap<>(); expectedDataMap.put("foods", expectedFoods); expectedDataMap.put("greetings", expectedGreetings); MultiBundleResourceFilter filter = ResourceFilterFactory.getMultiBundleResourceFilter(MultiBundleCSVFilter.ID); try (InputStream inStream = this.getClass().getResourceAsStream("/test-multi.csv")) { Map<String, LanguageBundle> bundles = filter.parse(inStream, new FilterOptions(Locale.ENGLISH)); assertEquals("Number of modules", expectedDataMap.size(), bundles.size()); for (Entry<String, LanguageBundle> bundleEntry : bundles.entrySet()) { String module = bundleEntry.getKey(); LanguageBundle bundle = bundleEntry.getValue(); TestResourceStringData[] expStrings = expectedDataMap.get(module); assertNotNull("Module " + module, expStrings); List<ResourceString> resStrings = bundle.getSortedResourceStrings(); assertEquals("Number of resource strings for module " + module, expStrings.length, resStrings.size()); int idx = 0; for (ResourceString resString : resStrings) { String key = resString.getKey(); String value = resString.getValue(); int seqNum = resString.getSequenceNumber(); TestResourceStringData expected = expStrings[idx++]; assertEquals("Resource key in module (" + module + ") at index " + idx, expected.key, key); assertEquals("Resource value in module(" + module + ") at index " + idx, expected.value, value); assertEquals("Resource sequence number in module(" + module + ") at index " + idx, expected.seq, seqNum); } } } catch (IOException e) { fail(e.getMessage()); } catch (ResourceFilterException e) { fail(e.getMessage()); } }