JavaPropertiesResource extends ResourceFilter { static String unescapeMessagePattern(String inputStr, MessagePatternEscape msgPatEsc) throws ResourceFilterException { if (inputStr.indexOf("''") < 0) { return inputStr; } MessagePattern msgPat = new MessagePattern(ApostropheMode.DOUBLE_OPTIONAL); try { msgPat.parse(inputStr); if (msgPatEsc == MessagePatternEscape.AUTO && !hasArgs(msgPat)) { return inputStr; } } catch (Exception e) { if (msgPatEsc == MessagePatternEscape.ALL) { throw new ResourceFilterException("Illegal message pattern string: " + inputStr); } return inputStr; } StringBuilder buf = new StringBuilder(); int start = 0; PrevState prev = PrevState.OTHER; boolean inQuote = false; for (int i = 0; i < msgPat.countParts(); i++) { Part part = msgPat.getPart(i); int limit = part.getLimit(); int endIdx = limit; Type type = part.getType(); if (type == Type.ARG_START) { if (prev == PrevState.DEFERRED_APOSTROPHE && (limit - start) == 1) { buf.append("'"); } prev = PrevState.OTHER; } else if (type == Type.SKIP_SYNTAX) { boolean curApos = msgPat.getSubstring(part).equals("'"); boolean doubleApos = false; if (curApos) { doubleApos = inputStr.charAt(limit - 2) == '\''; } if (doubleApos) { boolean emitSecondApos = false; if (inQuote) { emitSecondApos = true; prev = PrevState.OTHER; } else if (prev == PrevState.ARG_LIMIT) { if (start == limit - 2) { emitSecondApos = true; prev = PrevState.OTHER; } else { prev = PrevState.DEFERRED_APOSTROPHE; } } else { prev = PrevState.DEFERRED_APOSTROPHE; } if (!emitSecondApos) { endIdx = part.getIndex(); } } else { prev = PrevState.OTHER; if (curApos) { inQuote = !inQuote; } } } else if (type == Type.ARG_LIMIT) { prev = PrevState.ARG_LIMIT; } else { prev = PrevState.OTHER; } buf.append(inputStr.substring(start, endIdx)); start = limit; } if (start < inputStr.length()) { buf.append(inputStr.substring(start, inputStr.length())); } return buf.toString(); } JavaPropertiesResource(Encoding enc, MessagePatternEscape msgPatEsc);  JavaPropertiesResource(); @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 testUnescapeMessagePattern() throws ResourceFilterException { for (String[] testCase : MESSAGE_PATTERN_TEST_CASES) { String result = JavaPropertiesResource.unescapeMessagePattern(testCase[1], MessagePatternEscape.AUTO); String expected = testCase.length >= 4 && testCase[3] != null ? testCase[3] : testCase[0]; assertEquals("unescapeMessagePattern(" + testCase[1] + ", AUTO)", expected, result); } for (String[] testCase : MESSAGE_PATTERN_TEST_CASES) { String input = testCase.length >= 3 && testCase[2] != null ? testCase[2] : testCase[1]; String result = JavaPropertiesResource.unescapeMessagePattern(input, MessagePatternEscape.ALL); String expected = testCase.length >= 5 && testCase[4] != null ? testCase[4] : testCase[0]; assertEquals("unescapeMessagePattern(" + input + ", ALL)", expected, result); } }