1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs2.provider.zip;
18
19 import static org.junit.jupiter.api.Assertions.assertNotNull;
20 import static org.junit.jupiter.api.Assertions.assertTrue;
21
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.nio.file.Paths;
28 import java.nio.file.StandardCopyOption;
29 import java.util.Locale;
30 import java.util.regex.Pattern;
31
32 import javax.xml.parsers.DocumentBuilder;
33 import javax.xml.parsers.DocumentBuilderFactory;
34 import javax.xml.parsers.ParserConfigurationException;
35
36 import org.apache.commons.vfs2.FileObject;
37 import org.apache.commons.vfs2.FileSystemException;
38 import org.apache.commons.vfs2.FileSystemManager;
39 import org.apache.commons.vfs2.VFS;
40 import org.junit.jupiter.api.AfterEach;
41 import org.junit.jupiter.api.BeforeEach;
42 import org.junit.jupiter.api.Test;
43 import org.w3c.dom.Document;
44 import org.xml.sax.SAXException;
45
46
47
48
49 public class ParseXmlInZipTest {
50
51 private Locale defaultLocale;
52
53 @BeforeEach
54 public void changeDefaultLocale() {
55
56 defaultLocale = Locale.getDefault();
57
58
59 Locale.setDefault(new Locale("en", "US"));
60 }
61
62 private Path createTempFile() throws IOException {
63 final Path zipFile = Paths.get("src/test/resources/test-data/read-xml-tests.zip");
64 final Path newZipFile = Files.createTempFile(getClass().getSimpleName(), ".zip");
65 newZipFile.toFile().deleteOnExit();
66 Files.copy(zipFile, newZipFile, StandardCopyOption.REPLACE_EXISTING);
67 return newZipFile;
68 }
69
70 private DocumentBuilder newDocumentBuilder(final FileObject containerFile, final FileObject sourceFile,
71 final String pathToXsdInZip) throws IOException {
72 final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
73 final boolean validate = pathToXsdInZip != null;
74 documentBuilderFactory.setValidating(validate);
75 documentBuilderFactory.setNamespaceAware(true);
76 if (validate) {
77 documentBuilderFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
78 "http://www.w3.org/2001/XMLSchema");
79 @SuppressWarnings("resource")
80 final FileObject schema = containerFile.resolveFile(pathToXsdInZip);
81 if (!schema.exists()) {
82 schema.close();
83 throw new FileNotFoundException(schema.toString());
84 }
85 documentBuilderFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource",
86 schema.getContent().getInputStream());
87 }
88 DocumentBuilder documentBuilder = null;
89 try {
90 documentBuilder = documentBuilderFactory.newDocumentBuilder();
91 documentBuilder.setEntityResolver(new TestEntityResolver(containerFile, sourceFile));
92 } catch (final ParserConfigurationException e) {
93 throw new IOException("Cannot read Java Connector configuration: " + e, e);
94 }
95 documentBuilder.setErrorHandler(new TestErrorHandler(containerFile + " - " + sourceFile));
96 return documentBuilder;
97 }
98
99 @AfterEach
100 public void resetDefaultLocale() {
101 Locale.setDefault(defaultLocale);
102 }
103
104 @Test
105 public void testParseXmlInZip() throws IOException, SAXException {
106 final Path newZipFile = createTempFile();
107 final String xmlFilePath = "zip:file:" + newZipFile.toAbsolutePath() + "!/read-xml-tests/file1.xml";
108 final FileSystemManager manager = VFS.getManager();
109 try (FileObject zipFileObject = manager.resolveFile(xmlFilePath)) {
110 try (InputStream inputStream = zipFileObject.getContent().getInputStream()) {
111 final Document document = newDocumentBuilder(zipFileObject, zipFileObject, null).parse(inputStream);
112 assertNotNull(document);
113 }
114 }
115 }
116
117 @Test
118 public void testResolveAndParseBiggerXmlInZip() throws IOException, SAXException {
119
120
121
122 testResolveAndParseXmlInZip("read-xml-tests/file3-bigger.xml", null);
123 }
124
125 @Test
126 public void testResolveAndParseInvalidXml() throws IOException, SAXException {
127 try {
128 testResolveAndParseXmlInZip("read-xml-tests/name-invalid.xml", "/read-xml-tests/name.xsd");
129 } catch (final SAXException e) {
130 final Pattern p = Pattern.compile("Invalid content was found starting with element.+FOO");
131 assertTrue(p.matcher(e.toString()).find());
132 }
133 }
134
135 @Test
136 public void testResolveAndParseNotWellFormedXml() throws IOException {
137 try {
138 testResolveAndParseXmlInZip("read-xml-tests/name-not-well-formed.xml", "/read-xml-tests/name.xsd");
139 } catch (final SAXException e) {
140 assertTrue(
141 e.toString().contains("XML document structures must start and end within the same entity."));
142 }
143 }
144
145 @Test
146 public void testResolveAndParseXmlInZip() throws IOException, SAXException {
147
148
149
150 testResolveAndParseXmlInZip("read-xml-tests/file1.xml", null);
151 }
152
153 private void testResolveAndParseXmlInZip(final String xmlPathInZip, final String xsdPathInZip)
154 throws IOException, FileSystemException, SAXException {
155 final Path newZipFile = createTempFile();
156 final String zipFilePath = "zip:file:" + newZipFile.toAbsolutePath();
157 final FileSystemManager manager = VFS.getManager();
158 try (FileObject zipFileObject = manager.resolveFile(zipFilePath)) {
159 try (FileObject xmlFileObject = zipFileObject.resolveFile(xmlPathInZip)) {
160 try (InputStream inputStream = xmlFileObject.getContent().getInputStream()) {
161 final Document document = newDocumentBuilder(zipFileObject, xmlFileObject, xsdPathInZip)
162 .parse(inputStream);
163 assertNotNull(document);
164 }
165 }
166 }
167 }
168
169 @Test
170 public void testResolveAndParseXmlInZipWithOneXmlSchema() throws IOException, SAXException {
171 testResolveAndParseXmlInZip("read-xml-tests/name-with-xsd-ref.xml", "/read-xml-tests/name.xsd");
172 }
173
174 @Test
175 public void testResolveAndParseXmlInZipWithTwoXmlSchema() throws IOException, SAXException {
176 testResolveAndParseXmlInZip("read-xml-tests/person.xml", "/read-xml-tests/person.xsd");
177 }
178
179 }