| /* Copyright 2005 The Apache Software Foundation | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| package misc.detailed; | |
| import common.Common; | |
| import jira.xmlbeans177.TestListDocument; | |
| import jira.xmlbeans177A.TestListADocument; | |
| import org.apache.xmlbeans.XmlException; | |
| import org.apache.xmlbeans.XmlOptionCharEscapeMap; | |
| import org.apache.xmlbeans.XmlOptions; | |
| import org.junit.Test; | |
| import java.io.File; | |
| import java.util.HashMap; | |
| import static org.junit.Assert.*; | |
| public class CharEscapeTest extends Common | |
| { | |
| static final String inputFile = | |
| XBEAN_CASE_ROOT + P + "misc" + P + "jira" + P + "xmlbeans_177.xml"; | |
| static final String inputFile2 = | |
| XBEAN_CASE_ROOT + P + "misc" + P + "jira" + P + "xmlbeans_177a.xml"; | |
| //static final String outputDir = OUTPUTROOT + P + "misc"; | |
| //static final String outputFile1 = "xmlbeans_177_out1.xml"; | |
| //static final String outputFile2 = "xmlbeans_177_out2.xml"; | |
| static final String start = "<jira:testList xmlns:jira=\"http://jira/xmlbeans_177\">"; | |
| static final String end = "</jira:testList>"; | |
| static final String start2 = "<jira:testListA xmlns:jira=\"http://jira/xmlbeans_177a\">"; | |
| static final String end2 = "</jira:testListA>"; | |
| @Test | |
| public void testAddMapping() throws Exception | |
| { | |
| XmlOptionCharEscapeMap charEsc = new XmlOptionCharEscapeMap(); | |
| // a brand new map does not contain predefined entities | |
| assertNull(charEsc.getEscapedString('<')); | |
| assertNull(charEsc.getEscapedString('>')); | |
| assertNull(charEsc.getEscapedString('&')); | |
| assertNull(charEsc.getEscapedString('\'')); | |
| assertNull(charEsc.getEscapedString('"')); | |
| // test predefined entities | |
| charEsc.addMapping('<', XmlOptionCharEscapeMap.PREDEF_ENTITY); | |
| charEsc.addMapping('>', XmlOptionCharEscapeMap.PREDEF_ENTITY); | |
| charEsc.addMapping('&', XmlOptionCharEscapeMap.PREDEF_ENTITY); | |
| charEsc.addMapping('\'', XmlOptionCharEscapeMap.PREDEF_ENTITY); | |
| charEsc.addMapping('"', XmlOptionCharEscapeMap.PREDEF_ENTITY); | |
| assertEquals("<", charEsc.getEscapedString('<')); | |
| assertEquals(">", charEsc.getEscapedString('>')); | |
| assertEquals("&", charEsc.getEscapedString('&')); | |
| assertEquals("'", charEsc.getEscapedString('\'')); | |
| assertEquals(""", charEsc.getEscapedString('"')); | |
| // additions can be overwritten | |
| charEsc.addMapping('<', XmlOptionCharEscapeMap.HEXADECIMAL); | |
| assertEquals("<", charEsc.getEscapedString('<')); | |
| charEsc.addMapping('<', XmlOptionCharEscapeMap.DECIMAL); | |
| assertEquals("<", charEsc.getEscapedString('<')); | |
| // test some other characters | |
| assertNull(charEsc.getEscapedString('A')); | |
| charEsc.addMapping('A', XmlOptionCharEscapeMap.DECIMAL); | |
| charEsc.addMapping('B', XmlOptionCharEscapeMap.HEXADECIMAL); | |
| assertEquals("A", charEsc.getEscapedString('A')); | |
| assertEquals("B", charEsc.getEscapedString('B')); | |
| // non-xml entities cannot be escaped as predefined entities | |
| try | |
| { | |
| charEsc.addMapping('C', XmlOptionCharEscapeMap.PREDEF_ENTITY); | |
| fail("should have thrown an exception"); | |
| } | |
| catch (Exception e) | |
| { | |
| //System.out.println(e.getMessage()); | |
| assertTrue(e instanceof XmlException); | |
| String msg = "the PREDEF_ENTITY mode can only be used for the following characters: <, >, &, \" and '"; | |
| assertTrue(e.getMessage().endsWith(msg)); | |
| } | |
| } | |
| @Test | |
| public void testAddMappings() throws Exception | |
| { | |
| XmlOptionCharEscapeMap charEsc = new XmlOptionCharEscapeMap(); | |
| // non-xml entities cannot be escaped as predefined entities | |
| try | |
| { | |
| charEsc.addMappings('A', 'Z', XmlOptionCharEscapeMap.PREDEF_ENTITY); | |
| fail("should have thrown an exception"); | |
| } | |
| catch (Exception e) | |
| { | |
| assertTrue(e instanceof XmlException); | |
| String msg = "the PREDEF_ENTITY mode can only be used for the following characters: <, >, &, \" and '"; | |
| assertTrue(e.getMessage().endsWith(msg)); | |
| } | |
| // start char must be before end char | |
| try | |
| { | |
| charEsc.addMappings('a', 'Z', XmlOptionCharEscapeMap.HEXADECIMAL); | |
| fail("should have thrown an exception"); | |
| } | |
| catch (Exception e) | |
| { | |
| assertTrue(e instanceof XmlException); | |
| String msg = "ch1 must be <= ch2"; | |
| assertTrue(e.getMessage().endsWith(msg)); | |
| } | |
| charEsc.addMappings('A', 'Z', XmlOptionCharEscapeMap.HEXADECIMAL); | |
| assertEquals("A", charEsc.getEscapedString('A')); | |
| assertEquals("B", charEsc.getEscapedString('B')); | |
| assertEquals("C", charEsc.getEscapedString('C')); | |
| assertEquals("X", charEsc.getEscapedString('X')); | |
| assertEquals("Y", charEsc.getEscapedString('Y')); | |
| assertEquals("Z", charEsc.getEscapedString('Z')); | |
| // overwrite a mapping | |
| charEsc.addMapping('X', XmlOptionCharEscapeMap.DECIMAL); | |
| assertEquals("X", charEsc.getEscapedString('X')); | |
| assertEquals("Y", charEsc.getEscapedString('Y')); | |
| assertEquals("Z", charEsc.getEscapedString('Z')); | |
| } | |
| @Test | |
| public void testEscape1() throws Exception | |
| { | |
| File f = new File(inputFile); | |
| TestListDocument doc = TestListDocument.Factory.parse(f); | |
| // default behavior: without the character replacement map, | |
| // only the minimal, required characters are escaped | |
| String exp1 = start + "\n" + | |
| " <test>This is a greater than sign: ></test>\n" + | |
| " <test>This is a less than sign: <</test>\n" + | |
| " <test>This is a single quote: '</test>\n" + | |
| " <test>This is a double quote: \"</test>\n" + | |
| " <test>W.L.Gore & Associates</test>\n" + | |
| " <test>Character data may not contain the three-character sequence ]]> with the > unescaped.</test>\n" + | |
| " <test>In particular, character data in a CDATA section may not contain the three-character sequence ]]&gt; with the > unescaped.</test>\n" + | |
| end; | |
| assertEquals(exp1, doc.xmlText().replaceFirst("(?s)<!--.*-->","")); | |
| XmlOptionCharEscapeMap charEsc = new XmlOptionCharEscapeMap(); | |
| charEsc.addMapping('>', XmlOptionCharEscapeMap.PREDEF_ENTITY); | |
| XmlOptions opts = new XmlOptions(); | |
| opts.setSaveSubstituteCharacters(charEsc); | |
| // escape '>' as predefined entity as well | |
| String exp2 = start + "\n" + | |
| " <test>This is a greater than sign: ></test>\n" + | |
| " <test>This is a less than sign: <</test>\n" + | |
| " <test>This is a single quote: '</test>\n" + | |
| " <test>This is a double quote: \"</test>\n" + | |
| " <test>W.L.Gore & Associates</test>\n" + | |
| " <test>Character data may not contain the three-character sequence ]]> with the > unescaped.</test>\n" + | |
| " <test>In particular, character data in a CDATA section may not contain the three-character sequence ]]&gt; with the > unescaped.</test>\n" + | |
| end; | |
| assertEquals(exp2, doc.xmlText(opts).replaceFirst("(?s)<!--.*-->","")); | |
| // escape block of chars as hexadecimal | |
| charEsc.addMappings('A', 'D', XmlOptionCharEscapeMap.HEXADECIMAL); | |
| // opts holds a reference to charEsc, so opts is updated | |
| String exp3 = start + "\n" + | |
| " <test>This is a greater than sign: ></test>\n" + | |
| " <test>This is a less than sign: <</test>\n" + | |
| " <test>This is a single quote: '</test>\n" + | |
| " <test>This is a double quote: \"</test>\n" + | |
| " <test>W.L.Gore & Associates</test>\n" + | |
| " <test>Character data may not contain the three-character sequence ]]> with the > unescaped.</test>\n" + | |
| " <test>In particular, character data in a CDATA section may not contain the three-character sequence ]]&gt; with the > unescaped.</test>\n" + | |
| end; | |
| assertEquals(exp3, doc.xmlText(opts).replaceFirst("(?s)<!--.*-->","")); | |
| /* | |
| File od = new File(outputDir); | |
| od.mkdir(); | |
| File of1 = new File(od, outputFile1); | |
| File of2 = new File(od, outputFile2); | |
| doc.save(of1); | |
| doc.save(of2, opts); | |
| */ | |
| } | |
| @Test | |
| public void testEscape2() throws Exception | |
| { | |
| TestListDocument doc = TestListDocument.Factory.newInstance(); | |
| TestListDocument.TestList testList = doc.addNewTestList(); | |
| XmlOptionCharEscapeMap charEsc = new XmlOptionCharEscapeMap(); | |
| // define a block | |
| charEsc.addMappings('a', 'z', XmlOptionCharEscapeMap.DECIMAL); | |
| // overwrite | |
| charEsc.addMapping('x', XmlOptionCharEscapeMap.HEXADECIMAL); | |
| charEsc.addMapping('>', XmlOptionCharEscapeMap.PREDEF_ENTITY); | |
| // pi | |
| charEsc.addMapping('\u03c0', XmlOptionCharEscapeMap.HEXADECIMAL); | |
| XmlOptions opts = new XmlOptions(); | |
| opts.setSaveSubstituteCharacters(charEsc); | |
| HashMap prefixes = new HashMap(); | |
| prefixes.put("http://jira/xmlbeans_177", "jira"); | |
| opts.setSaveSuggestedPrefixes(prefixes); | |
| String[] testStrings = {"e < \u03c0", "\u03c0 > 3", "abcxyz"}; | |
| testList.setTestArray(testStrings); | |
| String exp = start + | |
| "<test>e < π</test>" + | |
| "<test>π > 3</test>" + | |
| "<test>abcxyz</test>" + | |
| end; | |
| assertEquals(exp, doc.xmlText(opts)); | |
| } | |
| @Test | |
| public void testEscapeAttribute() throws Exception | |
| { | |
| File f = new File(inputFile2); | |
| TestListADocument doc = TestListADocument.Factory.parse(f); | |
| // default behavior: without the character replacement map, | |
| // only the minimal, required characters are escaped | |
| String exp1 = start2 + "\n" + | |
| " <test a=\"This is a greater than sign: >\"/>\n" + | |
| " <test a=\"This is a less than sign: <\"/>\n" + | |
| " <test a=\"This is a single quote: '\"/>\n" + | |
| " <test a=\"This is a double quote: "\"/>\n" + | |
| " <test a=\"W.L.Gore & Associates\"/>\n" + | |
| end2; | |
| assertEquals(exp1, doc.xmlText().replaceFirst("(?s)<!--.*-->","")); | |
| XmlOptionCharEscapeMap charEsc = new XmlOptionCharEscapeMap(); | |
| charEsc.addMapping('>', XmlOptionCharEscapeMap.PREDEF_ENTITY); | |
| XmlOptions opts = new XmlOptions(); | |
| opts.setSaveSubstituteCharacters(charEsc); | |
| // escape '>' as predefined entity as well | |
| String exp2 = start2 + "\n" + | |
| " <test a=\"This is a greater than sign: >\"/>\n" + | |
| " <test a=\"This is a less than sign: <\"/>\n" + | |
| " <test a=\"This is a single quote: '\"/>\n" + | |
| " <test a=\"This is a double quote: "\"/>\n" + | |
| " <test a=\"W.L.Gore & Associates\"/>\n" + | |
| end2; | |
| assertEquals(exp2, doc.xmlText(opts).replaceFirst("(?s)<!--.*-->","")); | |
| // escape block of chars as hexadecimal | |
| charEsc.addMappings('A', 'D', XmlOptionCharEscapeMap.HEXADECIMAL); | |
| // opts holds a reference to charEsc, so opts is updated | |
| String exp3 = start2 + "\n" + | |
| " <test a=\"This is a greater than sign: >\"/>\n" + | |
| " <test a=\"This is a less than sign: <\"/>\n" + | |
| " <test a=\"This is a single quote: '\"/>\n" + | |
| " <test a=\"This is a double quote: "\"/>\n" + | |
| " <test a=\"W.L.Gore & Associates\"/>\n" + | |
| end2; | |
| assertEquals(exp3, doc.xmlText(opts).replaceFirst("(?s)<!--.*-->","")); | |
| } | |
| } |