/*
* eXist Open Source Native XML Database
* Copyright (C) 2011 The eXist-db Project
* http://exist-db.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id$
*/
package org.exist.validation;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
import org.exist.EXistException;
import org.exist.TestUtils;
import org.exist.collections.Collection;
import org.exist.collections.triggers.TriggerException;
import org.exist.security.PermissionDeniedException;
import org.exist.test.ExistEmbeddedServer;
import org.exist.util.Configuration;
import org.exist.util.LockException;
import org.exist.xquery.XPathException;
import org.exist.xquery.value.BooleanValue;
import org.exist.xquery.value.Item;
import org.exist.xquery.value.Sequence;
import org.junit.*;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.exist.TestUtils.GUEST_DB_USER;
import static org.exist.util.PropertiesBuilder.propertiesBuilder;
import static org.exist.validation.TestTools.executeQuery;
import static org.exist.validation.TestTools.storeDocument;
import static org.exist.validation.TestTools.storeTextDocument;
import static org.junit.Assert.*;
import org.exist.storage.BrokerPool;
import org.exist.storage.DBBroker;
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
import org.exist.util.XMLReaderObjectFactory;
import org.exist.xmldb.XmldbURI;
import org.xml.sax.SAXException;
/**
* Set of Tests for validation:validate($a) and validation:validate($a, $b)
* regarding validating using DTD's.
*
* @author Dannes Wessels (dizzzz@exist-db.org)
*/
public class ValidationFunctions_DTD_Test {
private final static String TEST_COLLECTION = "testValidationFunctionsDTD";
private final static XmldbURI VALIDATION_HOME_COLLECTION_URI = XmldbURI.ROOT_COLLECTION_URI.append(TEST_COLLECTION).append(TestTools.VALIDATION_HOME_COLLECTION);
private final static XmldbURI VALIDATION_DTD_COLLECTION_URI = VALIDATION_HOME_COLLECTION_URI.append(TestTools.VALIDATION_DTD_COLLECTION);
private final static XmldbURI VALIDATION_XSD_COLLECTION_URI = VALIDATION_HOME_COLLECTION_URI.append(TestTools.VALIDATION_XSD_COLLECTION);
private final static XmldbURI VALIDATION_TMP_COLLECTION_URI = VALIDATION_HOME_COLLECTION_URI.append(TestTools.VALIDATION_TMP_COLLECTION);
@ClassRule
public static final ExistEmbeddedServer existEmbeddedServer = new ExistEmbeddedServer(
propertiesBuilder()
.set(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE, "auto")
.build(),
true,
false);
@Test
public void validateUsingSystemCatalog() throws XPathException, PermissionDeniedException, EXistException {
// DTD for hamlet_valid.xml is registered in system catalog.
// result should be "document is valid"
final Sequence result = executeQuery(existEmbeddedServer.getBrokerPool(), "validation:validate( xs:anyURI('" + VALIDATION_TMP_COLLECTION_URI + "/hamlet_valid.xml'))");
assertEquals(1, result.getItemCount());
final Item r = result.itemAt(0);
assertTrue(r instanceof BooleanValue);
assertEquals( "hamlet_valid.xml in systemcatalog", BooleanValue.TRUE, r );
}
@Test
public void specifiedCatalog_test1() throws XPathException, PermissionDeniedException, EXistException {
final Sequence result = executeQuery(existEmbeddedServer.getBrokerPool(), "validation:validate(xs:anyURI('" + VALIDATION_HOME_COLLECTION_URI + "/hamlet_valid.xml') ," +" xs:anyURI('" + VALIDATION_DTD_COLLECTION_URI + "/catalog.xml'))");
assertEquals(1, result.getItemCount());
final Item r = result.itemAt(0);
assertTrue(r instanceof BooleanValue);
assertEquals("valid document", BooleanValue.TRUE, r );
}
@Test
public void specifiedCatalog_test2() throws XPathException, PermissionDeniedException, EXistException {
final Sequence result = executeQuery(existEmbeddedServer.getBrokerPool(), "validation:validate(xs:anyURI('" + VALIDATION_HOME_COLLECTION_URI + "/hamlet_invalid.xml'), xs:anyURI('" + VALIDATION_DTD_COLLECTION_URI + "/catalog.xml'))");
assertEquals(1, result.getItemCount());
final Item r = result.itemAt(0);
assertTrue(r instanceof BooleanValue);
assertEquals( "invalid document", BooleanValue.FALSE, r );
}
@Test
public void specifiedCatalog_test3() throws XPathException, PermissionDeniedException, EXistException {
final Sequence result = executeQuery(existEmbeddedServer.getBrokerPool(), "validation:validate(xs:anyURI('" + VALIDATION_HOME_COLLECTION_URI + "/hamlet_valid.xml'), xs:anyURI('" + VALIDATION_XSD_COLLECTION_URI + "/catalog.xml'))");
assertEquals(1, result.getItemCount());
final Item r = result.itemAt(0);
assertTrue(r instanceof BooleanValue);
assertEquals("wrong catalog", BooleanValue.FALSE, r);
}
@Test
public void specifiedCatalog_test4() throws XPathException, PermissionDeniedException, EXistException {
final Sequence result = executeQuery(existEmbeddedServer.getBrokerPool(), "validation:validate(xs:anyURI('" + VALIDATION_HOME_COLLECTION_URI + "/hamlet_invalid.xml'), xs:anyURI('" + VALIDATION_XSD_COLLECTION_URI + "/catalog.xml'))");
assertEquals(1, result.getItemCount());
final Item r = result.itemAt(0);
assertTrue(r instanceof BooleanValue);
assertEquals("wrong catalog, invalid document", BooleanValue.FALSE, r );
}
@Test
public void specifiedGrammar_dtd_forValidDoc() throws XPathException, PermissionDeniedException, EXistException {
final Sequence result = executeQuery(existEmbeddedServer.getBrokerPool(), "validation:validate(xs:anyURI('" + VALIDATION_HOME_COLLECTION_URI + "/hamlet_valid.xml'), xs:anyURI('" + VALIDATION_DTD_COLLECTION_URI + "/hamlet.dtd'))");
assertEquals(1, result.getItemCount());
final Item r = result.itemAt(0);
assertTrue(r instanceof BooleanValue);
assertEquals("valid document", BooleanValue.TRUE, r );
}
@Test
public void specifiedGrammar_dtd_forInvalidDoc() throws XPathException, PermissionDeniedException, EXistException {
final Sequence result = executeQuery(existEmbeddedServer.getBrokerPool(), "validation:validate( xs:anyURI('" + VALIDATION_HOME_COLLECTION_URI + "/hamlet_invalid.xml'), xs:anyURI('" + VALIDATION_DTD_COLLECTION_URI + "/hamlet.dtd') )");
assertEquals(1, result.getItemCount());
final Item r = result.itemAt(0);
assertTrue(r instanceof BooleanValue);
assertEquals( "invalid document", BooleanValue.FALSE, r );
}
@Test
public void searchedGrammar_valid_dtd() throws XPathException, PermissionDeniedException, EXistException {
final Sequence result = executeQuery(existEmbeddedServer.getBrokerPool(), "validation:validate( xs:anyURI('" + VALIDATION_HOME_COLLECTION_URI + "/hamlet_valid.xml'), xs:anyURI('" + VALIDATION_DTD_COLLECTION_URI + "/'))");
assertEquals(1, result.getItemCount());
final Item r = result.itemAt(0);
assertTrue(r instanceof BooleanValue);
assertEquals("valid document", BooleanValue.TRUE, r );
}
@Test
public void searchedGrammar_valid_xsd() throws XPathException, PermissionDeniedException, EXistException {
final Sequence result = executeQuery(existEmbeddedServer.getBrokerPool(), "validation:validate( xs:anyURI('" + VALIDATION_HOME_COLLECTION_URI + "/hamlet_valid.xml'), xs:anyURI('" + VALIDATION_XSD_COLLECTION_URI + "/') )");
assertEquals(1, result.getItemCount());
final Item r = result.itemAt(0);
assertTrue(r instanceof BooleanValue);
assertEquals( "valid document, not found", BooleanValue.FALSE, r );
}
@Test
public void searchedGrammar_valid() throws XPathException, PermissionDeniedException, EXistException {
final Sequence result = executeQuery(existEmbeddedServer.getBrokerPool(), "validation:validate(xs:anyURI('" + VALIDATION_HOME_COLLECTION_URI + "/hamlet_valid.xml'), xs:anyURI('/db/'))");
assertEquals(1, result.getItemCount());
final Item r = result.itemAt(0);
assertTrue(r instanceof BooleanValue);
assertEquals("valid document", BooleanValue.TRUE, r );
}
@Test
public void searchedGrammar_invalid() throws XPathException, PermissionDeniedException, EXistException {
final Sequence result = executeQuery(existEmbeddedServer.getBrokerPool(), "validation:validate(xs:anyURI('" + VALIDATION_HOME_COLLECTION_URI + "/hamlet_invalid.xml'), xs:anyURI('/db/'))");
assertEquals(1, result.getItemCount());
final Item r = result.itemAt(0);
assertTrue(r instanceof BooleanValue);
assertEquals( "invalid document", BooleanValue.FALSE, r );
}
@BeforeClass
public static void startup() throws SAXException, PermissionDeniedException, EXistException, IOException, LockException {
//create the collections we need for these tests
createTestCollections();
//create the documents we need for the tests
createTestDocuments();
}
@Before
public void clearGrammarCache() throws XPathException, PermissionDeniedException, EXistException {
executeQuery(existEmbeddedServer.getBrokerPool(), "validation:clear-grammar-cache()");
}
@AfterClass
public static void shutdown() throws Exception {
removeTestCollections();
}
private static void createTestCollections() throws EXistException, PermissionDeniedException, IOException, TriggerException {
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
final TransactionManager transact = pool.getTransactionManager();
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()));
final Txn txn = transact.beginTransaction()) {
/* create necessary collections if they don't exist */
final Collection validationCol = broker.getOrCreateCollection(txn, VALIDATION_HOME_COLLECTION_URI);
validationCol.getPermissions().setOwner(GUEST_DB_USER);
broker.saveCollection(txn, validationCol);
final Collection dtdCol = broker.getOrCreateCollection(txn, VALIDATION_DTD_COLLECTION_URI);
dtdCol.getPermissions().setOwner(GUEST_DB_USER);
broker.saveCollection(txn, dtdCol);
final Collection xsdCol = broker.getOrCreateCollection(txn, VALIDATION_XSD_COLLECTION_URI);
xsdCol.getPermissions().setOwner(GUEST_DB_USER);
broker.saveCollection(txn, xsdCol);
final Collection tmpCol = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI + "/" + TestTools.VALIDATION_TMP_COLLECTION));
tmpCol.getPermissions().setOwner(GUEST_DB_USER);
broker.saveCollection(txn, tmpCol);
transact.commit(txn);
}
}
private static void createTestDocuments() throws EXistException, PermissionDeniedException, LockException, SAXException, IOException {
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
final Configuration config = pool.getConfiguration();
final TransactionManager transact = pool.getTransactionManager();
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getGuestSubject()));
final Txn txn = transact.beginTransaction()) {
/* create necessary documents */
//hamlet
String sb = new String(TestUtils.readHamletSampleXml(), UTF_8);
sb = sb.replaceAll("\\Q<!\\E.*DOCTYPE.*\\Q-->\\E",
"<!DOCTYPE PLAY PUBLIC \"-//PLAY//EN\" \"play.dtd\">" );
final Collection tmpCol = broker.getCollection(VALIDATION_TMP_COLLECTION_URI);
storeDocument(broker, txn, tmpCol, "hamlet_valid.xml", sb);
final String prevValidationMode = (String)config.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE);
config.setProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE, "no");
final Path dtd = TestUtils.resolveSample("validation/dtd");
final Collection dtdCol = broker.getCollection(VALIDATION_DTD_COLLECTION_URI);
storeTextDocument(broker, txn, dtdCol, "hamlet.dtd", dtd.resolve("hamlet.dtd"));
storeDocument(broker, txn, dtdCol, "catalog.xml", dtd.resolve("catalog.xml"));
final Collection validationCol = broker.getCollection(VALIDATION_HOME_COLLECTION_URI);
storeDocument(broker, txn, validationCol, "hamlet_valid.xml", dtd.resolve("hamlet_valid.xml"));
storeDocument(broker, txn, validationCol, "hamlet_invalid.xml", dtd.resolve("hamlet_invalid.xml"));
config.setProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE, prevValidationMode);
transact.commit(txn);
}
}
private static void removeTestCollections() throws EXistException, PermissionDeniedException, IOException, TriggerException {
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
final TransactionManager transact = pool.getTransactionManager();
try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()));
final Txn txn = transact.beginTransaction()) {
final Collection testCollection = broker.getOrCreateCollection(txn, VALIDATION_HOME_COLLECTION_URI);
broker.removeCollection(txn, testCollection);
transact.commit(txn);
}
}
}