/* * eXist Open Source Native XML Database * Copyright (C) 2016 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 program; if not, write to the Free Software Foundation * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ package org.exist; import java.io.IOException; import java.io.StringWriter; import java.util.Optional; import java.util.Properties; import javax.xml.transform.OutputKeys; import org.exist.EXistException; import org.exist.Indexer; import org.exist.collections.Collection; import org.exist.collections.IndexInfo; import org.exist.security.AuthenticationException; import org.exist.security.PermissionDeniedException; 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.test.ExistEmbeddedServer; import org.exist.test.TestConstants; import org.exist.util.Configuration; import org.exist.util.DatabaseConfigurationException; import org.exist.util.LockException; import org.exist.util.serializer.SAXSerializer; import org.exist.xmldb.XmldbURI; import org.exist.xquery.XPathException; import org.exist.xquery.XQuery; import org.exist.xquery.value.Item; import org.exist.xquery.value.Sequence; import org.exist.xquery.value.SequenceIterator; import org.junit.*; import static org.junit.Assert.assertEquals; import org.xml.sax.SAXException; /** * Tests the indexer. * * @author ljo */ public class IndexerTest3 { @ClassRule public static final ExistEmbeddedServer existEmbeddedServer = new ExistEmbeddedServer(true, false); private final static String XML1 = "<?xml version=\"1.0\"?>\n" + "<k>\n" + "<l>a <b>b</b> c <d> d </d> <e> </e> f</l>\n" + "<m> a <b>b</b> c <d> d </d> <e> </e> f </m>\n" + "<n> a<b>b</b> c <d> d </d> <e> </e>f </n>\n" + "<o> <b>b</b> c <d> d </d> <e> </e> </o>\n" + "</k>\n"; private final static String XML2 = "<?xml version=\"1.0\"?>\n" + "<k>\n" + "<l>a <b>b</b> c <d> d </d> <e> </e> f</l>\n" + "</k>\n"; private final static String XML3 = "<?xml version=\"1.0\"?>\n" + "<k>\n" + "<m> a <b>b</b> c <d> d </d> <e> </e> f </m>\n" + "</k>\n"; private final static String XML4 = "<?xml version=\"1.0\"?>\n" + "<k>\n" + "<n> a<b>b</b> c <d> d </d> <e> </e>f </n>\n" + "</k>\n"; private final static String XML5 = "<?xml version=\"1.0\"?>\n" + "<k>\n" + "<o> <b>b</b> c <d> d </d> <e> </e> </o>\n" + "</k>\n"; private final static String XML6 = "<?xml version=\"1.0\"?>\n" + "<k>\n" + "<!-- a comment with whitespace leading, intermediate\n" + " and trailing -->\n" + "</k>\n"; private final static String XML7 = "<?xml version=\"1.0\"?>\n" + "<k>\n" + " <o> leading and trailing </o>\n" + "</k>\n"; private final static String RESULT_SUPPRESS_WS_NONE_XML1 = "<result>" + "<k>\n" + "<l>a <b>b</b> c <d> d </d> <e> </e> f</l>\n" + "<m> a <b>b</b> c <d> d </d> <e> </e> f </m>\n" + "<n> a<b>b</b> c <d> d </d> <e> </e>f </n>\n" + "<o> <b>b</b> c <d> d </d> <e> </e> </o>\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_NONE_XML2 = "<result>" + "<k>\n" + "<l>a <b>b</b> c <d> d </d> <e> </e> f</l>\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_NONE_XML3 = "<result>" + "<k>\n" + "<m> a <b>b</b> c <d> d </d> <e> </e> f </m>\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_NONE_XML4 = "<result>" + "<k>\n" + "<n> a<b>b</b> c <d> d </d> <e> </e>f </n>\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_NONE_XML5 = "<result>" + "<k>\n" + "<o> <b>b</b> c <d> d </d> <e> </e> </o>\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_NONE_XML6 = "<result>" + "<k>\n" + "<!-- a comment with whitespace leading, intermediate\n" + " and trailing -->\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_NONE_XML7 = "<result>" + "<k>\n" + " <o> leading and trailing </o>\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_LEADING_XML1 = "<result>" + "<k>" + "<l>a <b>b</b> c <d>d </d> <e> </e> f</l>" + "<m>a <b>b</b> c <d>d </d> <e> </e> f </m>" + "<n>a<b>b</b> c <d>d </d> <e> </e>f </n>" + "<o> <b>b</b> c <d>d </d> <e> </e> </o>" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_LEADING_XML2 = "<result>" + "<k>" + "<l>a <b>b</b> c <d>d </d> <e> </e> f</l>" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_LEADING_XML3 = "<result>" + "<k>" + "<m>a <b>b</b> c <d>d </d> <e> </e> f </m>" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_LEADING_XML4 = "<result>" + "<k>" + "<n>a<b>b</b> c <d>d </d> <e> </e>f </n>" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_LEADING_XML5 = "<result>" + "<k>" + "<o> <b>b</b> c <d>d </d> <e> </e> </o>" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_LEADING_XML6 = "<result>" + "<k>\n" + "<!-- a comment with whitespace leading, intermediate\n" + " and trailing -->\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_LEADING_XML7 = "<result>" + "<k>\n" + " <o>leading and trailing </o>\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_TRAILING_XML1 = "<result>" + "<k>" + "<l>a <b>b</b> c <d> d</d> <e> </e> f</l>" + "<m> a <b>b</b> c <d> d</d> <e> </e> f</m>" + "<n> a<b>b</b> c <d> d</d> <e> </e>f</n>" + // kolla " a" och "f " "<o> <b>b</b> c <d> d</d> <e> </e> </o>" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_TRAILING_XML2 = "<result>" + "<k>" + "<l>a <b>b</b> c <d> d</d> <e> </e> f</l>" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_TRAILING_XML3 = "<result>" + "<k>" + "<m> a <b>b</b> c <d> d</d> <e> </e> f</m>" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_TRAILING_XML4 = "<result>" + "<k>" + "<n> a<b>b</b> c <d> d</d> <e> </e>f</n>" + // kolla " a" och "f " "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_TRAILING_XML5 = "<result>" + "<k>" + "<o> <b>b</b> c <d> d</d> <e> </e> </o>" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_TRAILING_XML6 = "<result>" + "<k>\n" + "<!-- a comment with whitespace leading, intermediate\n" + " and trailing -->\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_TRAILING_XML7 = "<result>" + "<k>\n" + " <o> leading and trailing</o>\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_BOTH_XML1 = "<result>" + "<k>\n" + "<l>a <b>b</b> c <d>d</d> <e> </e> f</l>\n" + // kolla "a" "<m>a <b>b</b> c <d>d</d> <e> </e> f</m>\n" + // kolla "f " "<n>a<b>b</b> c <d>d</d> <e> </e>f</n>\n" + "<o> <b>b</b> c <d>d</d> <e> </e> </o>\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_BOTH_XML2 = "<result>" + "<k>\n" + "<l>a <b>b</b> c <d>d</d> <e> </e> f</l>\n" + // kolla "a" "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_BOTH_XML3 = "<result>" + "<k>\n" + "<m>a <b>b</b> c <d>d</d> <e> </e> f</m>\n" + // kolla "f " "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_BOTH_XML4 = "<result>" + "<k>\n" + "<n>a<b>b</b> c <d>d</d> <e> </e>f</n>\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_BOTH_XML5 = "<result>" + "<k>\n" + "<o> <b>b</b>c <d>d</d> <e> </e> </o>\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_BOTH_XML6 = "<result>" + "<k>\n" + "<!-- a comment with whitespace leading, intermediate\n" + " and trailing -->\n" + "</k>" + "</result>"; private final static String RESULT_SUPPRESS_WS_BOTH_XML7 = "<result>" + "<k>\n" + " <o>leading and trailing</o>\n" + "</k>" + "</result>"; private final static String XQUERY = "let $test := doc('" + TestConstants.TEST_COLLECTION_URI.toString() + "/" + TestConstants.TEST_XML_URI.toString() + "') " + "return " + " <result>{$test/k}</result>"; private void store_suppress_type(final String propValue, final String xml) throws PermissionDeniedException, IOException, EXistException, SAXException, LockException, AuthenticationException { final BrokerPool pool = existEmbeddedServer.getBrokerPool(); pool.getConfiguration().setProperty(Indexer.PROPERTY_SUPPRESS_WHITESPACE, propValue); // Make sure to keep preserve whitespace mixed content stable even if default changes. fixme! - should test both. /ljo boolean propWSMValue = false; pool.getConfiguration().setProperty(Indexer.PROPERTY_PRESERVE_WS_MIXED_CONTENT, propWSMValue); final TransactionManager txnMgr = pool.getTransactionManager(); try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().authenticate("admin", ""))); final Txn txn = txnMgr.beginTransaction()) { final Collection collection = broker.getOrCreateCollection(txn, TestConstants.TEST_COLLECTION_URI); final IndexInfo info = collection.validateXMLResource(txn, broker, TestConstants.TEST_XML_URI, xml); //TODO : unlock the collection here ? collection.store(txn, broker, info, xml); @SuppressWarnings("unused") final org.exist.dom.persistent.DocumentImpl doc = info.getDocument(); broker.flush(); broker.saveCollection(txn, collection); txnMgr.commit(txn); } } private String store_and_retrieve_suppress_type(final String type, final String typeXml, final String typeXquery) throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { store_suppress_type(type, typeXml); final BrokerPool pool = existEmbeddedServer.getBrokerPool(); try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject())); final StringWriter out = new StringWriter()) { final XQuery xquery = pool.getXQueryService(); final Sequence result = xquery.execute(broker, typeXquery, null); final Properties props = new Properties(); props.setProperty(OutputKeys.INDENT, "no"); final SAXSerializer serializer = new SAXSerializer(out, props); serializer.startDocument(); for (final SequenceIterator i = result.iterate(); i.hasNext(); ) { final Item next = i.nextItem(); next.toSAX(broker, serializer, props); } serializer.endDocument(); return out.toString(); } } @Test public void retrieve_suppress_ws_none1() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_NONE_XML1, store_and_retrieve_suppress_type("none", XML1, XQUERY)); } @Test public void retrieve_suppress_ws_none2() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_NONE_XML2, store_and_retrieve_suppress_type("none", XML2, XQUERY)); } @Test public void retrieve_suppress_ws_none3() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_NONE_XML3, store_and_retrieve_suppress_type("none", XML3, XQUERY)); } @Test public void retrieve_suppress_ws_none4() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_NONE_XML4, store_and_retrieve_suppress_type("none", XML4, XQUERY)); } @Test public void retrieve_suppress_ws_none5() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_NONE_XML5, store_and_retrieve_suppress_type("none", XML5, XQUERY)); } @Test public void retrieve_suppress_ws_none6() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_NONE_XML6, store_and_retrieve_suppress_type("none", XML6, XQUERY)); } @Test public void retrieve_suppress_ws_none7() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_NONE_XML7, store_and_retrieve_suppress_type("none", XML7, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_leading1() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_LEADING_XML1, store_and_retrieve_suppress_type("leading", XML1, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_leading2() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_LEADING_XML2, store_and_retrieve_suppress_type("leading", XML2, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_leading3() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_LEADING_XML3, store_and_retrieve_suppress_type("leading", XML3, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_leading4() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_LEADING_XML4, store_and_retrieve_suppress_type("leading", XML4, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_leading5() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_LEADING_XML5, store_and_retrieve_suppress_type("leading", XML5, XQUERY)); } @Test public void retrieve_suppress_ws_leading6() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_LEADING_XML6, store_and_retrieve_suppress_type("leading", XML6, XQUERY)); } @Test public void retrieve_suppress_ws_leading7() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_LEADING_XML7, store_and_retrieve_suppress_type("leading", XML7, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_trailing1() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_TRAILING_XML1, store_and_retrieve_suppress_type("trailing", XML1, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_trailing2() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_TRAILING_XML2, store_and_retrieve_suppress_type("trailing", XML2, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_trailing3() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_TRAILING_XML3, store_and_retrieve_suppress_type("trailing", XML3, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_trailing4() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_TRAILING_XML4, store_and_retrieve_suppress_type("trailing", XML4, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_trailing5() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_TRAILING_XML5, store_and_retrieve_suppress_type("trailing", XML5, XQUERY)); } @Test public void retrieve_suppress_ws_trailing6() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_TRAILING_XML6, store_and_retrieve_suppress_type("trailing", XML6, XQUERY)); } @Test public void retrieve_suppress_ws_trailing7() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_TRAILING_XML7, store_and_retrieve_suppress_type("trailing", XML7, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_both1() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_BOTH_XML1, store_and_retrieve_suppress_type("both", XML1, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_both2() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_BOTH_XML2, store_and_retrieve_suppress_type("both", XML2, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_both3() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_BOTH_XML3, store_and_retrieve_suppress_type("both", XML3, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_both4() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_BOTH_XML4, store_and_retrieve_suppress_type("both", XML4, XQUERY)); } @Ignore @Test public void retrieve_suppress_ws_both5() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_BOTH_XML5, store_and_retrieve_suppress_type("both", XML5, XQUERY)); } @Test public void retrieve_suppress_ws_both6() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_BOTH_XML6, store_and_retrieve_suppress_type("both", XML6, XQUERY)); } @Test public void retrieve_suppress_ws_both7() throws EXistException, IOException, LockException, AuthenticationException, PermissionDeniedException, SAXException, XPathException { assertEquals(RESULT_SUPPRESS_WS_BOTH_XML7, store_and_retrieve_suppress_type("both", XML7, XQUERY)); } }