/*
* Copyright (C) 2009 eXo Platform SAS.
*
* This 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.1 of
* the License, or (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.services.jcr.api.importing;
import org.exoplatform.services.ext.action.InvocationContext;
import org.exoplatform.services.jcr.core.ExtendedSession;
import org.exoplatform.services.jcr.impl.util.StringConverter;
import org.exoplatform.services.jcr.impl.xml.importing.ContentImporter;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Random;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.InvalidSerializedDataException;
import javax.jcr.ItemExistsException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.ConstraintViolationException;
/**
* Created by The eXo Platform SAS
*
* @author <a href="mailto:Sergey.Kabashnyuk@gmail.com">Sergey Kabashnyuk</a>
* @version $Id: TestDocumentViewImport.java 14244 2008-05-14 11:44:54Z ksm $
*/
public class TestDocumentViewImport extends AbstractImportTest
{
private static Log log = ExoLogger.getLogger("exo.jcr.component.core.TestDocumentViewImport");
private final String docView =
"<exo:test xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" "
+ "xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" "
+ "xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" "
+ "xmlns:exo=\"http://www.exoplatform.com/jcr/exo/1.0\" "
+ "xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" "
+ "jcr:primaryType=\"nt:unstructured\">"
+ "<childNode jcr:created=\"2004-08-18T20:07:42.626+01:00\" jcr:primaryType=\"nt:folder\">"
+ "<childNode3 jcr:created=\"2004-08-18T20:07:42.636+01:00\" jcr:primaryType=\"nt:file\">"
+ "<jcr:content jcr:data=\"dGhpcyBpcyB0aGUgYmluYXJ5IGNvbnRlbnQ=\" jcr:primaryType=\"nt:resource\" jcr:lastModified=\"2004-08-18T20:07:42.626+01:00\" jcr:mimeType=\"text/html\" jcr:uuid=\"1092852462407_\">"
+ "</jcr:content>"
+ "</childNode3>"
+ "<childNode2 jcr:created=\"2004-08-18T20:07:42.636+01:00\" jcr:primaryType=\"nt:file\">"
+ "<jcr:content jcr:data=\"VGhyZWUgYnl0ZXMgYXJlIGNvbmNhdGVuYXRlZCwgdGhlbiBzcGxpdCB0byBmb3JtIDQgZ3JvdXBz"
+ "IG9mIDYtYml0cyBlYWNoOw==\" jcr:primaryType=\"nt:resource\" jcr:mimeType=\"text/html\" jcr:lastModified=\"2004-08-18T20:07:42.626+01:00\" jcr:uuid=\"1092852462406_\">"
+ "</jcr:content>"
+ "</childNode2>"
+ "</childNode>"
+ "<testNodeWithText1 jcr:mixinTypes='mix:referenceable' jcr:uuid='id_uuidNode3' testProperty='test property value'>Thisi is a text content of node <testNodeWithText1/> </testNodeWithText1>"
+ "<testNodeWithText2><![CDATA[This is a text content of node <testNodeWithText2>]]></testNodeWithText2>"
+ "<uuidNode1 jcr:mixinTypes='mix:referenceable' jcr:uuid='id_uuidNode1' source='docView'/>" + "</exo:test>";
private final String docView2 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<childNode2 " + "xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" "
+ "xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" " + "jcr:primaryType=\"nt:file\" "
+ "jcr:created=\"2004-08-18T17:17:00.856+03:00\">" + "<jcr:content " + "jcr:primaryType=\"nt:resource\" "
+ "jcr:uuid=\"6a3859dac0a8004b006e6e0bf444ebaa\" " + "jcr:data=\"dGhpcyBpcyB0aGUgYmluYXJ5IGNvbnRlbnQ=\" "
+ "jcr:lastModified=\"2004-08-18T17:17:00.856+03:00\" "
+ "jcr:lastModified2=\"2004-08-18T17:17:00.856+03:00\" " + "jcr:mimeType=\"text/text\"/>" + "</childNode2>";
private final String docViewECM =
"<test-article xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:kfx=\"http://www.exoplatform.com/jcr/kfx/1.1/\" xmlns:Fwd=\"http://www.exoplatform.com/jcr/Fwd/1.1/\" xmlns:Re=\"http://www.exoplatform.com/jcr/Re/1.1/\" xmlns:rma=\"http://www.rma.com/jcr/\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" xmlns:fn=\"http://www.w3.org/2004/10/xpath-functions\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:exo=\"http://www.exoplatform.com/jcr/exo/1.0\" exo:summary=\"\" exo:voteTotal=\"0\" exo:votingRate=\"0.0\" jcr:primaryType=\"exo:article\" jcr:mixinTypes=\"mix:votable mix:i18n\" jcr:uuid=\"6da3fcebc0a800070043d28761e00078\" exo:language=\"en\" exo:title=\"title\" exo:text=\"\"></test-article>";
private final String NAV_XML =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<node-navigation>" + "<owner-type>portal</owner-type>"
+ "<owner-id>portalone</owner-id>" + "<access-permissions>*:/guest</access-permissions>" + "<page-nodes>"
+ "<node>" + "<uri>portalone::home</uri>" + "<name>home</name>" + "<label>Home</label>"
+ "<page-reference>portal::portalone::content</page-reference>" + "</node>" + "<node>"
+ "<uri>portalone::register</uri>" + "<name>register</name>" + "<label>Register</label>"
+ "<page-reference>portal::portalone::register</page-reference>" + "</node>" + "</page-nodes>"
+ "</node-navigation>";
private final String NAV_XML2 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<node-navigation xmlns:jcr='http://www.jcp.org/jcr/1.0' jcr:primaryType='nt:unstructured' >"
+ "<owner-type>portal</owner-type>" + "<owner-id>portalone</owner-id>"
+ "<access-permissions>*:/guest</access-permissions>" + "<page-nodes>" + "<node>"
+ "<uri>portalone::home</uri>" + "<name>home</name>" + "<label>Home</label>"
+ "<page-reference>portal::portalone::content</page-reference>" + "</node>" + "<node>"
+ "<uri>portalone::register</uri>" + "<name>register</name>" + "<label>Register</label>"
+ "<page-reference>portal::portalone::register</page-reference>" + "</node>" + "</page-nodes>"
+ "</node-navigation>";
private final String xmlSameNameSablings4Xmltext = "<html><body>a<b>b</b>c</body></html>";
private final String xmlSpeacialChars = "<html><body>a<b>b</b>c</body></html>";
private final Random random;
public TestDocumentViewImport()
{
super();
random = new Random();
}
public void testDocImportUnExistingPropertyDefinition() throws Exception
{
InvocationContext context = new InvocationContext();
try
{
context.put(ContentImporter.RESPECT_PROPERTY_DEFINITIONS_CONSTRAINTS, true);
((ExtendedSession)session)
.importXML(root.getPath(), new ByteArrayInputStream(docView2.getBytes()), 0, context);
session.save();
fail();
}
catch (RepositoryException e)
{
// ok
}
try
{
context.put(ContentImporter.RESPECT_PROPERTY_DEFINITIONS_CONSTRAINTS, false);
((ExtendedSession)session)
.importXML(root.getPath(), new ByteArrayInputStream(docView2.getBytes()), 0, context);
session.save();
}
catch (RepositoryException e)
{
e.printStackTrace();
fail();
}
}
public void testDocViewImportContentHandler() throws Exception
{
XMLReader reader = XMLReaderFactory.createXMLReader();
root.addNode("test");
reader.setContentHandler(session.getImportContentHandler("/test", 0));
InputSource inputSource = new InputSource(new ByteArrayInputStream(docView.getBytes()));
reader.parse(inputSource);
// fail ("STOP");
session.save();
Node root = session.getRootNode();
NodeIterator iterator = root.getNode("test/exo:test").getNodes();
assertEquals(4, iterator.getSize());
iterator = root.getNode("test/exo:test/childNode").getNodes();
assertEquals(2, iterator.getSize());
Property property = root.getProperty("test/exo:test/childNode/childNode2/jcr:content/jcr:data");
assertEquals("Three bytes are concatenated, then split to form 4 groups of 6-bits each;", property.getString());
// property =
// root.getProperty("childNode/childNode3/jcr:content/exo:content");
// assertEquals("this is the binary content", property.getString());
}
public void testFindNodeType() throws Exception
{
Node testRoot = root.addNode("testRoot", "nt:folder");
try
{
deserialize(testRoot, XmlSaveType.SESSION, true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW,
new ByteArrayInputStream(NAV_XML.getBytes()));
testRoot.getSession().save();
fail();
}
catch (ConstraintViolationException e)
{
}
try
{
deserialize(testRoot, XmlSaveType.SESSION, false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW,
new ByteArrayInputStream(NAV_XML.getBytes()));
testRoot.getSession().save();
fail();
}
catch (SAXException e)
{
}
}
public void testImportDocumentViewContentHandlerInvalidChildNodeType() throws Exception
{
Node testRoot = root.addNode("testRoot", "nt:folder");
Node exportRoot = root.addNode("exportRoot", "exo:article");
exportRoot.setProperty("exo:title", "title");
exportRoot.setProperty("exo:text", "text");
session.save();
byte[] content = serialize(exportRoot, false, true);
try
{
deserialize(testRoot, XmlSaveType.SESSION, false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW,
new ByteArrayInputStream(content));
testRoot.getSession().save();
fail();
}
catch (SAXException e)
{
}
}
public void testImportDocumentViewStreamInvalidChildNodeType() throws Exception
{
Node testRoot = root.addNode("testRoot", "nt:folder");
Node exportRoot = root.addNode("exportRoot", "exo:article");
exportRoot.setProperty("exo:title", "title");
exportRoot.setProperty("exo:text", "text");
session.save();
byte[] content = serialize(exportRoot, false, true);
try
{
deserialize(testRoot, XmlSaveType.SESSION, true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW,
new ByteArrayInputStream(content));
testRoot.getSession().save();
fail();
}
catch (RepositoryException e)
{
}
}
public void testImportDocView() throws RepositoryException, InvalidSerializedDataException,
ConstraintViolationException, IOException, ItemExistsException
{
root.addNode("test2");
session.importXML("/test2", new ByteArrayInputStream(docView.getBytes()), 0);
session.save();
Node root = session.getRootNode().getNode("test2");
NodeIterator iterator = root.getNodes();
assertEquals(1, iterator.getSize());
// log.debug(">>"+session.getWorkspaceDataContainer()); iterator =
iterator = root.getNode("exo:test/childNode").getNodes();
assertEquals(2, iterator.getSize());
Property property = root.getProperty("exo:test/childNode/childNode3/jcr:content/jcr:data");
assertEquals("this is the binary content", property.getString());
property = root.getProperty("exo:test/childNode/childNode2/jcr:content/jcr:data");
assertEquals("Three bytes are concatenated, then split to form 4 groups of 6-bits each;", property.getString());
}
public void testImportDocViewECM() throws RepositoryException, InvalidSerializedDataException,
ConstraintViolationException, IOException, ItemExistsException
{
root.addNode("testECM");
session.importXML("/testECM", new ByteArrayInputStream(docViewECM.getBytes()), 0);
session.save();
Node testEcmNode = session.getRootNode().getNode("testECM");
NodeIterator iterator = testEcmNode.getNodes();
assertEquals(1, iterator.getSize());
Node nodeArticle = root.getNode("testECM/test-article");
assertEquals("title", nodeArticle.getProperty("exo:title").getString());
}
public void testImportRawXml() throws Exception
{
Node testRoot = root.addNode("testRoot", "exo:registryGroup");
session.save();
deserialize(testRoot, XmlSaveType.SESSION, true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW,
new ByteArrayInputStream(NAV_XML.getBytes()));
testRoot.getSession().save();
Node node_navigation = testRoot.getNode("node-navigation");
assertTrue(node_navigation.isNodeType("exo:registryEntry"));
Node owner_type = node_navigation.getNode("owner-type");
assertTrue(owner_type.isNodeType("nt:unstructured"));
}
public void testImportRawXmlFail() throws Exception
{
Node testRoot = root.addNode("testRoot", "exo:registryGroup");
session.save();
try
{
deserialize(testRoot, XmlSaveType.SESSION, true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW,
new ByteArrayInputStream(NAV_XML2.getBytes()));
testRoot.getSession().save();
fail();
}
catch (ConstraintViolationException e)
{
// ok
}
}
public void testImportVersionableFile() throws Exception
{
Node testPdf = root.addNode("testPdf", "nt:file");
Node contentTestPdfNode = testPdf.addNode("jcr:content", "nt:resource");
try
{
File file = createBLOBTempFile(25);// 2.5M
contentTestPdfNode.setProperty("jcr:data", new FileInputStream(file));
contentTestPdfNode.setProperty("jcr:mimeType", "application/octet-stream");
}
catch (IOException e)
{
throw new RepositoryException(e);
}
contentTestPdfNode.setProperty("jcr:lastModified", session.getValueFactory().createValue(Calendar.getInstance()));
session.save();
testPdf.addMixin("mix:versionable");
session.save();
testPdf.checkin();
testPdf.checkout();
testPdf.checkin();
byte[] buf = serialize(testPdf, false, true);
Node importRoot = root.addNode("ImportRoot");
deserialize(importRoot, XmlSaveType.SESSION, true, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW,
new ByteArrayInputStream(buf));
session.save();
assertTrue(importRoot.hasNode("testPdf"));
Node testRoot2 = importRoot.getNode("testPdf");
assertTrue(testRoot2.isNodeType("mix:versionable"));
}
public void testImportXmlCh() throws Exception
{
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler(session.getImportContentHandler(root.getPath(), 0));
InputSource inputSource = new InputSource(new ByteArrayInputStream(xmlSpeacialChars.getBytes()));
reader.parse(inputSource);
session.save();
Node htmlNode = root.getNode("html");
Node bodyNode = htmlNode.getNode("body");
Node xmlTextNode = bodyNode.getNode("jcr:xmltext");
String xmlChars = xmlTextNode.getProperty("jcr:xmlcharacters").getString();
assertTrue(StringConverter.denormalizeString(xmlSpeacialChars).contains(xmlChars));
}
public void testImportXmlChSameNameSablings() throws Exception
{
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler(session.getImportContentHandler(root.getPath(), 0));
InputSource inputSource = new InputSource(new ByteArrayInputStream(xmlSameNameSablings4Xmltext.getBytes()));
reader.parse(inputSource);
session.save();
Node htmlNode = root.getNode("html");
Node bodyNode = htmlNode.getNode("body");
NodeIterator xmlTextNodes = bodyNode.getNodes("jcr:xmltext");
assertEquals(2, xmlTextNodes.getSize());
}
public void testImportXmlStream() throws Exception
{
session.importXML(root.getPath(), new ByteArrayInputStream(xmlSpeacialChars.getBytes()),
ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
session.save();
Node htmlNode = root.getNode("html");
Node bodyNode = htmlNode.getNode("body");
Node xmlTextNode = bodyNode.getNode("jcr:xmltext");
String xmlChars = xmlTextNode.getProperty("jcr:xmlcharacters").getString();
assertTrue(StringConverter.denormalizeString(xmlSpeacialChars).contains(xmlChars));
}
public void testImportXmlStreamSameNameSablings() throws Exception
{
session.importXML(root.getPath(), new ByteArrayInputStream(xmlSameNameSablings4Xmltext.getBytes()),
ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
session.save();
Node htmlNode = root.getNode("html");
Node bodyNode = htmlNode.getNode("body");
NodeIterator xmlTextNodes = bodyNode.getNodes("jcr:xmltext");
assertEquals(2, xmlTextNodes.getSize());
Node nodeA = xmlTextNodes.nextNode();
Node nodeC = xmlTextNodes.nextNode();
assertEquals("a", nodeA.getProperty("jcr:xmlcharacters").getString());
assertEquals("c", nodeC.getProperty("jcr:xmlcharacters").getString());
}
}