blob: f0c40dcef1adfc75ce6d324034309409df8b9033 [file] [log] [blame]
package org.eclipse.gendoc.services.openoffice.test;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.gendoc.document.parser.documents.Unzipper;
import org.eclipse.gendoc.document.parser.documents.XMLParser;
import org.eclipse.gendoc.document.parser.documents.openoffice.OpenOfficeNamespaceContext;
import org.junit.Assert;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import junit.framework.TestCase;
public class OpenOfficeVerifyHelper {
public OpenOfficeVerifyHelper(String filePath, OpenOfficeNamespaceContext namespaceContext) throws IOException, ParserConfigurationException {
this.filePath = filePath;
this.namespaceContext = namespaceContext;
unzipper = new Unzipper(new File(filePath));
unzipper.unzip();
xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(namespaceContext);
parsers = new HashMap<String, XMLParser>();
try {
verifyXmls(URIUtil.toFile(URIUtil.toURI(FileLocator.resolve(new URL(
"platform:/plugin/org.eclipse.gendoc.services.openoffice.test/resources/schemas")))));
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}
public void dispose() {
if (unzipper != null) {
unzipper.clean();
unzipper = null;
}
}
public void verifyXmls(final File schemasLoc) throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
factory.setXIncludeAware(true);
factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource",
schemasLoc.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".xsd");
}
}));
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
File f = null;
if (systemId != null) {
int index = systemId.lastIndexOf('/');
if (index >= 0)
f = new File(schemasLoc,systemId.substring(index+1));
else
f = new File(schemasLoc,systemId);
} else {
return null;
}
return new InputSource(new FileInputStream(f));
}
});
builder.setErrorHandler(new ErrorHandler() {
@Override
public void warning(SAXParseException exception) throws SAXException {
warnings.add(exception);
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
errors.add(exception);
}
@Override
public void error(SAXParseException exception) throws SAXException {
errors.add(exception);
}
});
verifyXmlsImpl(unzipper.getUnzipDocumentFile(), builder);
}
private void verifyXmlsImpl(File dir, DocumentBuilder builder) {
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory() ||
pathname.getName().endsWith(".xml") ||
pathname.getName().equals(".xml.rels");
}
});
if (files == null)
return;
for (File f : files) {
String relPath = f.getPath().replace(
unzipper.getUnzipDocumentFile().getPath(), "").
replace(File.separator, "/");
if (f.isDirectory()) {
verifyXmlsImpl(f, builder);
} else {
if (relPath.endsWith("revisionInfo.xml"))
continue;
try {
InputStream in = new FileInputStream(f);
warnings = new ArrayList<SAXException>();
errors = new ArrayList<SAXException>();
Document doc = builder.parse(new InputSource(in));
filterErrorsFromIgnorablesNS(doc,errors);
TestCase.assertEquals("XML parsing errors '"+relPath+"': " + Arrays.toString(errors.toArray()), 0, errors.size());
TestCase.assertEquals("XML parsing warnings: '"+relPath+"'" + Arrays.toString(warnings.toArray()), 0, warnings.size());
} catch (Exception e) {
TestCase.fail(String.format("Fail verifying Open Office content '%s': %s",relPath, e.getMessage()));
}
}
}
}
private void filterErrorsFromIgnorablesNS(Document doc, List<SAXException> errors) {
if (errors.isEmpty())
return;
String text = doc.getDocumentElement().getAttributeNS("http://schemas.openxmlformats.org/markup-compatibility/2006","Ignorable");
if (text.isEmpty())
text = "";
String[] ignorables = ("xml mc "+text).split(" ");
for (int i=0; i<ignorables.length; i++) {
Iterator<SAXException> it = errors.iterator();
while (it.hasNext()) {
SAXException e = it.next();
String str = e.getMessage();
Pattern p = Pattern.compile("\\'"+ignorables[i]+"[a-zA-Z0-9]*\\:");
Matcher m = p.matcher(str);
if (m.find()) {
it.remove();
}
}
}
}
public void verifyEqual(String message, String file, String reg, String expected) {
try {
verify(message, 0, file, reg, expected);
} catch (XPathExpressionException e) {
throw new IllegalArgumentException(e);
}
}
public void verifyNotEqual(String message, String file, String reg, String expected) {
try {
verify(message, 1, file, reg, expected);
} catch (XPathExpressionException e) {
throw new IllegalArgumentException(e);
}
}
public void verifyNull(String message, String file, String reg) {
try {
verify(message, 2, file, reg, null);
} catch (XPathExpressionException e) {
throw new IllegalArgumentException(e);
}
}
public void verifyNotNull(String message, String file, String reg) {
try {
verify(message, 3, file, reg, null);
} catch (XPathExpressionException e) {
throw new IllegalArgumentException(e);
}
}
private void verify(String message, int op, String file, String reg, Object expected) throws XPathExpressionException {
XMLParser parser = parsers.get(file);
if (parser == null) {
parser = new XMLParser(new File(unzipper.getUnzipDocumentFile(),file));
parsers.put(file,parser);
}
Object value = (expected instanceof String) ?
xpath.evaluate(reg, parser.getDocument()).trim() :
xpath.evaluate(reg, parser.getDocument(), XPathConstants.NODE);
switch (op) {
case 0:
Assert.assertEquals(message,expected,value);
break;
case 1:
Assert.assertNotSame(message,expected,value);
break;
case 2:
Assert.assertNull(message,value);
break;
case 3:
Assert.assertNotNull(message,value);
break;
default:
}
}
private String filePath;
private OpenOfficeNamespaceContext namespaceContext;
private Unzipper unzipper;
private XPath xpath;
private Map<String,XMLParser> parsers;
private List<SAXException> warnings;
private List<SAXException> errors;
}