📄 exportdocviewtest.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.jackrabbit.test.api;import org.apache.jackrabbit.test.AbstractJCRTest;import org.apache.jackrabbit.test.XMLChar;import org.xml.sax.SAXException;import org.xml.sax.ContentHandler;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Attr;import org.w3c.dom.NamedNodeMap;import javax.xml.transform.sax.SAXTransformerFactory;import javax.xml.transform.sax.TransformerHandler;import javax.xml.transform.stream.StreamResult;import javax.xml.transform.stream.StreamSource;import javax.xml.transform.dom.DOMResult;import javax.xml.transform.TransformerException;import javax.xml.transform.TransformerFactory;import javax.xml.transform.Transformer;import javax.jcr.Session;import javax.jcr.Workspace;import javax.jcr.NamespaceRegistry;import javax.jcr.RepositoryException;import javax.jcr.Item;import javax.jcr.Node;import javax.jcr.NodeIterator;import javax.jcr.Property;import javax.jcr.PropertyType;import javax.jcr.PropertyIterator;import javax.jcr.Value;import java.util.Stack;import java.util.ArrayList;import java.util.Properties;import java.util.Enumeration;import java.io.File;import java.io.IOException;import java.io.BufferedOutputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.ByteArrayOutputStream;import java.io.StringWriter;/** * <code>ExportDocViewTest</code> tests the two Session methods : * {@link Session#exportDocumentView(String, ContentHandler, boolean, boolean)} * and {@link Session#exportDocumentView(String, java.io.OutputStream, boolean, boolean)} * against the required behaviours according the document view xml mapping * defined in the JSR 170 specification in chapter 6.4.2, 6.4.3 and 6.4.4 . * * @test * @sources ExportDocViewTest.java * @executeClass org.apache.jackrabbit.test.api.ExportDocViewTest * @keywords level1 */public class ExportDocViewTest extends AbstractJCRTest { private final boolean CONTENTHANDLER = true, STREAM = false; private final boolean SKIPBINARY = true, SAVEBINARY = false; private final boolean NORECURSE = true, RECURSE = false; /** * Resolved QName for jcr:xmltext */ private String JCR_XMLTEXT; /** * Resolved QName for jcr:xmlcharacters */ private String JCR_XMLDATA; /** * the stack of the text node values to check */ private Stack textValuesStack; private class StackEntry { // the list of text node values of the text nodes of an xml element ArrayList textValues; // the current position in the ArrayList int position = 0; } /** * indicates if the tested repository exports multivalued properties. */ private boolean exportMultivalProps = false; /** * indicates if the tested repository escapes (xml)invalid jcr names. */ private boolean exportInvalidXmlNames = false; private boolean skipBinary; private boolean noRecurse; private boolean withHandler; private File file; private Session session; private Workspace workspace; private NamespaceRegistry nsr; private String testPath; private Document doc; protected void setUp() throws Exception { isReadOnly = true; session = helper.getReadOnlySession(); workspace = session.getWorkspace(); nsr = workspace.getNamespaceRegistry(); file = File.createTempFile("docViewExportTest", ".xml"); super.setUp(); JCR_XMLTEXT = session.getNamespacePrefix(NS_JCR_URI) + ":xmltext"; JCR_XMLDATA = session.getNamespacePrefix(NS_JCR_URI) + ":xmlcharacters"; testPath = testRoot; } protected void tearDown() throws Exception { file.delete(); if (session != null) { session.logout(); } super.tearDown(); } public void testExportDocView_handler_session_skipBinary_noRecurse() throws IOException, RepositoryException, SAXException, TransformerException { doTestExportDocView(CONTENTHANDLER, SKIPBINARY, NORECURSE); } public void testExportDocView_handler_session_skipBinary_recurse() throws IOException, RepositoryException, SAXException, TransformerException { doTestExportDocView(CONTENTHANDLER, SKIPBINARY, RECURSE); } public void testExportDocView_handler_session_saveBinary_noRecurse() throws IOException, RepositoryException, SAXException, TransformerException { doTestExportDocView(CONTENTHANDLER, SAVEBINARY, NORECURSE); } public void testExportDocView_handler_session_saveBinary_recurse() throws IOException, RepositoryException, SAXException, TransformerException { doTestExportDocView(CONTENTHANDLER, SAVEBINARY, RECURSE); } public void testExportDocView_stream_session_skipBinary_recurse() throws IOException, RepositoryException, SAXException, TransformerException { doTestExportDocView(STREAM, SKIPBINARY, RECURSE); } public void testExportDocView_stream_session_skipBinary_noRecurse() throws IOException, RepositoryException, SAXException, TransformerException { doTestExportDocView(STREAM, SKIPBINARY, NORECURSE); } public void testExportDocView_stream_session_saveBinary_noRecurse() throws IOException, RepositoryException, SAXException, TransformerException { doTestExportDocView(STREAM, SAVEBINARY, NORECURSE); } public void testExportDocView_stream_session_saveBinary_recurse() throws IOException, RepositoryException, SAXException, TransformerException { doTestExportDocView(STREAM, SAVEBINARY, RECURSE); } /** * Tests session.exportDocView with the different argument possibilities. * The flag withHandler decides if the method requiring a ContentHandler as * argument is called. The class org.apache.xml.serialize.XMLSerializer is * taken as ContentHandler in this case. In both cases ( export with a * ContentHandler and export with Stream) the test node is exported to the * file defined in the setUp. This exported file is parsed using * javax.xml.transform package and the receiving document is compared with * the test node and its properties and child nodes in the repository. * * @param withHandler boolean, decides to call method requiring a * ContentHandler as argument * @param skipBinary * @param noRecurse */ public void doTestExportDocView(boolean withHandler, boolean skipBinary, boolean noRecurse) throws RepositoryException, IOException, SAXException, TransformerException { this.skipBinary = skipBinary; this.noRecurse = noRecurse; this.withHandler = withHandler; BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file)); try { if (withHandler) { SAXTransformerFactory stf = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); TransformerHandler th = stf.newTransformerHandler(); th.setResult(new StreamResult(os)); session.exportDocumentView(testPath, th, skipBinary, noRecurse); } else { session.exportDocumentView(testPath, os, skipBinary, noRecurse); } } finally { os.close(); } // build the DOM tree InputStream in = new BufferedInputStream(new FileInputStream(file)); doc = readDocument(in); compareTree(); } /** * Compares the test node with the document's root element. In case also the * child nodes are exported (noRecurse = false) the child nodes of the test * node are compared with the child elements of the root element too. * * @throws RepositoryException */ private void compareTree() throws RepositoryException, IOException { Element root = doc.getDocumentElement(); textValuesStack = new Stack(); // we assume the path is valid Item item = session.getItem(testPath); // only an absolute path to a node is allowed if (!item.isNode()) { fail("Item at the given root path " + testPath + " is not a node."); } Node node = (Node) item; // multival props exported? setExportMultivalProps(node, root, false); // items with invalid xml names exported? setExportInvalidXmlNames(node, root, false); // check the test root node checkRootElement(node, root); // check the namespaces compareNamespaces(root); // check the exported data against the node which is exported. compareNode(node, root); // check the whole tree if (!noRecurse) { checkChildNodes(node, root); } } /** * Assures that root element exists and has correct jcr:root name if it is * the root node of the repository. (chapter 6.4.2.2 of the JCR * specification.) Also checks if multivalued properties are exported * (chapter 6.4.2.5 of the JCR specification.) Also tries to find out if * items with an invalid xml name are exported or not. (chapter 6.4.2.4 of * the JCR specification.) * * @param node * @param root * @throws RepositoryException */ private void checkRootElement(Node node, Element root) throws RepositoryException { boolean isValidName = XMLChar.isValidName(node.getName()); if (root != null) { // check correct element name if the root node of the repository is exported. if (node.getDepth() == 0) { assertEquals("Exported root node has not correct name jcr:root.", "jcr:root", root.getTagName()); } } else { if (exportInvalidXmlNames || isValidName) { fail("Node " + node.getPath() + " is not exported."); } } } /** * Checks the child nodes of the given node against the child nodes of the * given xml element. The found text nodes of the xml element are hold in an * ArrayList and put on a stack for further checking if another child * element is between them. * * @param node * @param elem * @throws RepositoryException */ private void checkChildNodes(Node node, Element elem) throws RepositoryException, IOException { NodeIterator nodeIter = node.getNodes(); if (getSize(node.getNodes()) == 0) { assertTrue("Exported node " + node.getPath() + " has child elements " + "although it has no child nodes ", 0 == countChildElems(elem)); } else { // create a stack entry for the text child nodes // of the current xml element StackEntry entry = new StackEntry(); entry.textValues = getChildTextNodeValues(elem); textValuesStack.push(entry); // xmltext nodes directly following each other // are serialized together as xml text ArrayList jcrTextNodes = new ArrayList(); while (nodeIter.hasNext()) { Node childNode = nodeIter.nextNode(); if (isXMLTextNode(childNode)) { jcrTextNodes.add(childNode); } else { if (jcrTextNodes.size() > 0) { compareXmltextNodes(jcrTextNodes, elem); // reset the Array jcrTextNodes.clear(); } compareChildTree(childNode, elem); } } // finally we are through the child nodes // so we delete the stackEntry textValuesStack.pop(); } } /** * Compares the child tree of a given node against the child elements of a * given element. (chapter 6.4.2.1 points 2,3,4 of the JCR specification). * <p/> * Considered are the export constraints regarding nodes named jcr:xmldata * (chapter 6.4.2.3 of the JCR specification). * <p/> * Also the numbers of exported child elements is compared with the number * of child nodes. * * @param node * @param parentElem * @throws RepositoryException */ private void compareChildTree(Node node, Element parentElem) throws RepositoryException, IOException { Element nodeElem; // find a childElem belonging to the node and check it. nodeElem = findElem(node, parentElem); if (nodeElem != null) { compareNode(node, nodeElem); // go deep checkChildNodes(node, nodeElem); } } /** * Checks the given Element if it has a child element with the same (or * eventually escaped) name as the given node. (chapter 6.4.2.1 point 3 of * the JCR specification). * * @param node * @param parentElem * @return Child Element of parentElem. Null if no corresponidng element is * found. * @throws RepositoryException */ private Element findElem(Node node, Element parentElem) throws RepositoryException { String name = node.getName(); Element nodeElem = null; // valid xml name? boolean isValidName = XMLChar.isValidName(name); name = !isValidName ? escapeNames(name) : name; // same name sibs ArrayList children = getChildElems(parentElem, name); if (children.size() > 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -