AndroidStringsResource extends ResourceFilter { @Override public void merge(InputStream baseStream, OutputStream outStream, LanguageBundle languageBundle, FilterOptions options) throws IOException, ResourceFilterException { Map<String, String> kvMap = Utils.createKeyValueMap(languageBundle.getResourceStrings()); BreakIterator brkItr = Utils.getWordBreakIterator(options); BufferedReader reader = new BufferedReader(new InputStreamReader(baseStream, CHAR_SET)); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outStream, CHAR_SET)); String line; while ((line = reader.readLine()) != null) { if (line.matches(STR_ARRAY_OPEN_TAG_PTRN)) { String openingTag = line.substring(0, line.indexOf('>') + 1); String key = openingTag.substring(openingTag.indexOf('"') + 1, openingTag.lastIndexOf('"')); if (!kvMap.containsKey(key)) { writer.write(line); writer.newLine(); continue; } String value = kvMap.get(key); if (!(value.startsWith("[") && value.endsWith("]"))) { writer.write(line); writer.newLine(); continue; } String tabSubString = openingTag.substring(0, openingTag.indexOf('<')); String spaces = tabSubString + getTabStr(tabSubString); writer.write(openingTag); writer.newLine(); String[] items = value.substring(1, value.length() - 1).split(","); for (int i = 0; i < items.length; i++) { writer.write(formatMessage("<item>", items[i].trim(), "</item>", spaces, brkItr)); } writer.write(openingTag.substring(0, openingTag.indexOf('<'))); writer.write("</string-array>"); writer.newLine(); while ((line = reader.readLine()) != null && !line.matches(STR_ARRAY_CLOSE_TAG_PTRN)) ; } else if (line.matches(STR_OPEN_TAG_PTRN)) { String openingTag = line.substring(0, line.indexOf('>') + 1); String key = openingTag.substring(openingTag.indexOf('"') + 1, openingTag.lastIndexOf('"')); if (!kvMap.containsKey(key)) { writer.write(line); writer.newLine(); continue; } String value = kvMap.get(key); String spaces = openingTag.substring(0, openingTag.indexOf('<')); writer.write(formatMessage(openingTag.trim(), value, "</string>", spaces, brkItr)); while (line != null && !line.matches(STR_CLOSE_TAG_PTRN)) { line = reader.readLine(); } } else if (line.matches(PLURALS_OPEN_TAG_PTRN)) { String openingTag = line.substring(0, line.indexOf('>') + 1); String key = openingTag.substring(openingTag.indexOf('"') + 1, openingTag.lastIndexOf('"')); if (!kvMap.containsKey(key)) { writer.write(line); writer.newLine(); continue; } String value = kvMap.get(key); Map<String, String> plural_categories = null; if ((plural_categories = getPluralCategories(value)).isEmpty()) { writer.write(line); writer.newLine(); continue; } String tabSubString = openingTag.substring(0, openingTag.indexOf('<')); String spaces = tabSubString + getTabStr(tabSubString); writer.write(openingTag); writer.newLine(); for (String pKey : Constants.PLURAL_CATEGORIES) { if (plural_categories.containsKey(pKey)) { String pValue = plural_categories.get(pKey); String itemStr = "<item quantity=\"" + pKey + "\">"; writer.write(formatMessage(itemStr, pValue.trim(), "</item>", spaces, brkItr)); } } writer.write(openingTag.substring(0, openingTag.indexOf('<'))); writer.write("</plurals>"); writer.newLine(); while (line != null && !line.matches(PLURALS_CLOSE_TAG_PTRN)) { line = reader.readLine(); } } else { writer.write(line); writer.newLine(); } } writer.flush(); }  @Override LanguageBundle parse(InputStream inStream, FilterOptions options); @Override void write(OutputStream outStream, LanguageBundle languageBundle, FilterOptions options); @Override void merge(InputStream baseStream, OutputStream outStream, LanguageBundle languageBundle,
            FilterOptions options);  }
@Test public void testMerge() throws IOException, ResourceFilterException { File tempFile; tempFile = File.createTempFile(this.getClass().getSimpleName(), ".xml"); tempFile.deleteOnExit(); try (OutputStream os = new FileOutputStream(tempFile); InputStream is = new FileInputStream(MERGE_INPUT_1_FILE)) { res.merge(is, os, MERGE_BUNDLE, new FilterOptions(Locale.ENGLISH)); os.flush(); assertTrue(ResourceTestUtil.compareFiles(EXPECTED_MERGE_1_FILE, tempFile)); } tempFile = File.createTempFile(this.getClass().getSimpleName(), ".xml"); tempFile.deleteOnExit(); try (OutputStream os = new FileOutputStream(tempFile); InputStream is = new FileInputStream(MERGE_INPUT_2_FILE)) { res.merge(is, os, MERGE_BUNDLE, new FilterOptions(Locale.JAPANESE)); os.flush(); assertTrue(ResourceTestUtil.compareFiles(EXPECTED_MERGE_2_FILE, tempFile)); } }