/*
* Copyright (c) 2001-2007 Sun Microsystems, Inc. All rights reserved.
*
* The Sun Project JXTA(TM) Software License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment: "This product includes software
* developed by Sun Microsystems, Inc. for JXTA(TM) technology."
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must
* not be used to endorse or promote products derived from this software
* without prior written permission. For written permission, please contact
* Project JXTA at http://www.jxta.org.
*
* 5. Products derived from this software may not be called "JXTA", nor may
* "JXTA" appear in their name, without prior written permission of Sun.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN
* MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* JXTA is a registered trademark of Sun Microsystems, Inc. in the United
* States and other countries.
*
* Please see the license information page at :
* <http://www.jxta.org/project/www/license.html> for instructions on use of
* the license in source files.
*
* ====================================================================
*
* This software consists of voluntary contributions made by many individuals
* on behalf of Project JXTA. For more information on Project JXTA, please see
* http://www.jxta.org.
*
* This license is based on the BSD license adopted by the Apache Foundation.
*/
package net.jxta.document;
import java.io.*;
import java.util.Enumeration;
import java.util.Collections;
import java.util.List;
import java.security.ProviderException;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import net.jxta.document.Element;
import net.jxta.impl.document.LiteXMLDocument;
import net.jxta.impl.document.LiteXMLElement;
import net.jxta.impl.document.PlainTextDocument;
public final class DocumentTest extends TestCase {
final static String badlittleimpl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<!DOCTYPE jxta:MIA>\n"
+ "<jxta:MIA xmlns:jxta=\"http://jxta.org\">\n" + " <MSID/>\n" + " <Parm>\n" + " <Svc>\n"
+ " <jxta:MIA xmlns:jxta=\"http://jxta.org\">\n" + " <MSID/>\n" + " </jxta:MIA>\n" + " </Svc>\n"
+ " <Proto>\n" + " <jxta:MIA xmlns:jxta=\"http://jxta.org\">\n" + " <MSID/>\n" + " </jxta:MIA>\n"
+ " </Proto>\n" + " </Parm>\n" + " </jxta:MIA>\n";
final static String badInclusion = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<!DOCTYPE jxta:CP>"
+ "<jxta:CP type=\"jxta:PlatformConfig\" xmlns:jxta=\"http://jxta.org\">"
+ " <InfraDesc>"
+ " <?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<!DOCTYPE InfraDesc>"
+ "<InfraDesc>"
+ " Default Infrastructure NetPeerGroup Created by net.jxta.platform.NetworkConfigurator"
+ "</InfraDesc>"
+ " </InfraDesc>"
+ "</jxta:CP>";
public static class LiteXMLBug {
public LiteXMLBug(String xml) {
MimeMediaType mimeMediaType = MimeMediaType.XMLUTF8;
StringReader reader = new StringReader(xml);
try {
LiteXMLDocument document = (LiteXMLDocument)
LiteXMLDocument.INSTANTIATOR.newInstance(mimeMediaType, reader);
spew(document);
} catch (IOException caught) {
fail("should not have thrown an exception");
} finally {
reader.close();
}
}
public void spew(XMLElement element) {
System.out.println(element.getValue());
Enumeration<XMLElement> children = element.getChildren();
while (children.hasMoreElements()) {
XMLElement child = children.nextElement();
spew(child);
}
}
}
/** Creates new DocTest */
public DocumentTest(String name) {
super(name);
}
public static Test suite() {
TestSuite suite = new TestSuite(DocumentTest.class);
return suite;
}
private void _test(StructuredDocumentFactory.Instantiator instantiator, MimeMediaType type) {
try {
final String useDocType = "Test";
StructuredTextDocument doc = null;
try {
doc = (StructuredTextDocument) instantiator.newInstance(type, useDocType);
} catch (Throwable thrown) {
thrown.printStackTrace(System.err);
fail("exception thrown during construction!" + thrown.toString());
}
assertTrue("could not construct object for type : " + type, doc != null);
String itsType = doc.getName();
assertTrue("returned doctype does not equal type document was created with!", useDocType.equals(itsType));
assertTrue("returned doc name does not equal name of document element", doc.getName().equals(itsType));
TextElement testElement = doc.createElement("element");
doc.appendChild(testElement);
try {
Element firstchild = (Element) doc.getChildren().nextElement();
assertTrue("added a single element, but something else was returned", testElement.equals(firstchild));
} catch (Exception e) {
e.printStackTrace();
fail("added a single element, but it was not returned");
}
final String useName = "element2";
final String useValue = "value&<!";
TextElement testElement2 = doc.createElement(useName, useValue);
testElement.appendChild(testElement2);
String itsName = testElement2.getName();
assertTrue("name of element was not correct after creation", useName.equals(itsName));
String itsValue = testElement2.getTextValue();
assertTrue("value of element was not correct after creation. was '" + itsValue + "' should be '" + useValue + "'"
,
useValue.equals(itsValue));
testElement2 = doc.createElement("element3", useValue);
testElement.appendChild(testElement2);
testElement2 = doc.createElement("element4", "1");
testElement.appendChild(testElement2);
itsValue = testElement2.getTextValue();
assertTrue("value of element was not correct after creation (length 1)", "1".equals(itsValue));
if (type.getSubtype().equalsIgnoreCase("XML")) {
try {
TextElement testElement5 = doc.createElement("really wrong and long", "1");
fail("Tag names with spaces should be disallowed");
} catch (Exception failed) {// that's ok
}
}
int count = 0;
for (Enumeration<Element> eachChild = doc.getChildren(); eachChild.hasMoreElements(); count++, eachChild.nextElement()) {
;
}
assertTrue("Doc didnt have one child", 1 == count);
count = 0;
for (Enumeration<Element> eachChild = doc.getChildren("element"); eachChild.hasMoreElements(); count++, eachChild.nextElement()) {
;
}
assertTrue("Doc didnt have one child named 'element'", 1 == count);
count = 0;
for (Enumeration<Element> eachChild = doc.getChildren("bogus"); eachChild.hasMoreElements(); count++, eachChild.nextElement()) {
;
}
assertTrue(" Doc shouldnt have had a child named 'bogus'", 0 == count);
count = 0;
for (Enumeration<Element> eachChild = testElement.getChildren(); eachChild.hasMoreElements(); count++, eachChild.nextElement()) {
;
}
assertTrue("element didnt have expected number of children", 3 == count);
count = 0;
for (Enumeration<Element> eachChild = testElement.getChildren(useName); eachChild.hasMoreElements(); count++, eachChild.nextElement()) {
;
}
assertTrue("element didnt have expected number of children named '" + useName + "'", 1 == count);
// This check also is important for checking that the behaviour of the
// tree is correct when there are nodes with the same name as the parent in subtrees.
Element testElement3 = doc.createElement(useName, useValue);
testElement2.appendChild(testElement3);
testElement3 = doc.createElement(useName);
testElement2.appendChild(testElement3);
count = 0;
for (Enumeration eachChild = testElement2.getChildren(useName); eachChild.hasMoreElements(); count++, eachChild.nextElement()) {
;
}
assertTrue("element didnt have expected number of children named '" + useName + "'", 2 == count);
StructuredDocument likeMe = null;
try {
likeMe = (StructuredTextDocument) instantiator.newInstance(doc.getMimeType(), doc.getStream());
} catch (java.security.ProviderException thrown) {
;
} catch (Throwable thrown) {
thrown.printStackTrace();
fail("Exception thrown during reconstruction! " + thrown.toString());
}
if (testElement instanceof Attributable) {
_testAttributes((Attributable) testElement);
_testAttributes((Attributable) testElement3);
}
try {
likeMe = instantiator.newInstance(doc.getMimeType(), doc.getStream());
} catch (java.security.ProviderException thrown) {
;
} catch (Throwable thrown) {
thrown.printStackTrace();
fail("Exception thrown during reconstruction! " + thrown.toString());
}
Writer somewhere = new StringWriter();
(doc).sendToWriter(somewhere);
String docAsString = somewhere.toString().trim();
testElement3 = doc.createElement(useName, docAsString);
testElement2.appendChild(testElement3);
String docFromElement = (String) testElement3.getValue();
assertTrue("Could not faithfully store stream representation of doc in doc. (lengths dont match)",
docAsString.length() == docFromElement.length());
for (int eachChar = 0; eachChar < docAsString.length(); eachChar++) {
assertTrue("Could not faithfully store stream representation of doc in doc. (failed at index: " + eachChar + ")",
docAsString.charAt(eachChar) == docFromElement.charAt(eachChar));
}
Element testElement4 = doc.createElement("shortname", "shortvalue");
Element testElement5 = doc.createElement(
"looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongname",
"shortvalue");
Element testElement6 = doc.createElement(
"looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongname",
"looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongvalue");
Element testElement7 = doc.createElement("shortname",
"looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongvalue");
doc.appendChild(testElement4);
doc.appendChild(testElement5);
doc.appendChild(testElement6);
doc.appendChild(testElement7);
System.out.println(testElement4.toString());
// System.out.println( testElement5.toString() );
// System.out.println( testElement6.toString() );
// System.out.println( testElement7.toString() );
} catch (Throwable everything) {
everything.printStackTrace();
fail("caught an unexpected exception - " + everything.toString());
}
}
public void _testAttributes(Attributable element) {
try {
final String someName = "attrName";
final String someValue = "attrValue";
Enumeration<Attribute> attribs = element.getAttributes();
assertTrue("Element already had attributes!", !attribs.hasMoreElements());
assertTrue("New attribute returned previous value!", null == element.addAttribute(someName, someValue));
String oldValue = element.addAttribute(new Attribute(someName, someValue));
assertTrue("New attribute didnt return previous value!", (null != oldValue) && (oldValue.equals(someValue)));
Attribute anAttrib = element.getAttribute(someName);
assertTrue("Could not get attribute back!", null != anAttrib);
assertTrue("value of attribute was not correct", anAttrib.getValue().equals(someValue));
anAttrib = element.getAttribute("bogusName");
assertTrue("Should not have been able to get an unknown attribute name", null == anAttrib);
} catch (Throwable everything) {
everything.printStackTrace();
fail("Caught an unexpected exception - " + everything.toString());
}
}
private void _testConstructors(StructuredDocumentFactory.Instantiator instantiator, MimeMediaType type) {
try {
final String useDocType = "Test";
StructuredTextDocument doc = null;
doc = (StructuredTextDocument) instantiator.newInstance(type, useDocType);
doc = (StructuredTextDocument) instantiator.newInstance(type, useDocType, null);
doc = (StructuredTextDocument) instantiator.newInstance(type, useDocType, "value");
String stringdoc = doc.toString();
if (type.getSubtype().equalsIgnoreCase("XML")) {
try {
doc = (StructuredTextDocument) instantiator.newInstance(type, "Really wrong and long");
fail("Tag names with spaces should be disallowed");
} catch (Exception failed) {// that's ok
}
}
try {
doc = (StructuredTextDocument) instantiator.newInstance(type, new ByteArrayInputStream(stringdoc.getBytes()));
} catch (ProviderException notsupported) {// thats ok.
}
if (instantiator instanceof StructuredDocumentFactory.TextInstantiator) {
try {
doc = (StructuredTextDocument) ((StructuredDocumentFactory.TextInstantiator) instantiator).newInstance(type
,
new StringReader(stringdoc));
} catch (ProviderException notsupported) {// thats ok.
}
}
} catch (Throwable everything) {
everything.printStackTrace();
fail("Caught an unexpected exception - " + everything.toString());
}
}
public void _testAttributesSolo(StructuredDocumentFactory.Instantiator instantiator, MimeMediaType type) {
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
StructuredDocument doc = instantiator.newInstance(type, "Message");
assertTrue("should be no attributes", !((Attributable) doc).getAttributes().hasMoreElements());
((Attributable) doc).addAttribute("version", "123");
doc.sendToStream(os);
String old = ((Attributable) doc).addAttribute("version", "1xx23");
assertTrue("updating attribute gave wrong result", "123".equals(old));
doc.sendToStream(os);
List attrs = Collections.list(((Attributable) doc).getAttributes());
assertTrue("should be 1 attribute", 1 == attrs.size());
if (type.getSubtype().equalsIgnoreCase("XML")) {
try {
((Attributable) doc).addAttribute(new Attribute("really long and wrong", "whatever"));
fail("Attribute names with spaces should be disallowed");
} catch (Exception failed) {// that's ok
}
}
} catch (Throwable everything) {
everything.printStackTrace();
fail("Caught an unexpected exception - " + everything.toString());
}
}
public void _testLiteXMLEmptyElement(StructuredDocumentFactory.TextInstantiator instantiator, MimeMediaType type) {
try {
String doc = "<?xml version=\"1.0\"?><whatever/>";
XMLDocument xmldoc = (XMLDocument) instantiator.newInstance(type, new StringReader(doc));
Element anElement = xmldoc.createElement("whynot");
xmldoc.appendChild(anElement);
XMLElement anotherElement = xmldoc.createElement("why", "because");
anElement.appendChild(anotherElement);
System.out.println(xmldoc.toString());
StringWriter writer = new StringWriter();
xmldoc.sendToWriter(writer);
StringReader reader = new StringReader(writer.toString());
XMLDocument roundtrip = (XMLDocument) instantiator.newInstance(xmldoc.getMimeType(), reader);
System.out.println(roundtrip.toString());
StringWriter secondroundwriter = new StringWriter();
roundtrip.sendToWriter(secondroundwriter);
StringReader secondroundreader = new StringReader(secondroundwriter.toString());
XMLDocument secondroundtrip = (XMLDocument) instantiator.newInstance(roundtrip.getMimeType(), secondroundreader);
System.out.println(secondroundtrip.toString());
} catch (Throwable everything) {
everything.printStackTrace();
fail("Caught an unexpected exception - " + everything.toString());
}
}
public void testLiteXMLStructuredDoc() {
try {
_test(LiteXMLDocument.INSTANTIATOR, MimeMediaType.XML_DEFAULTENCODING);
_testConstructors(LiteXMLDocument.INSTANTIATOR, MimeMediaType.XML_DEFAULTENCODING);
_testAttributesSolo(LiteXMLDocument.INSTANTIATOR, MimeMediaType.XML_DEFAULTENCODING);
_testLiteXMLEmptyElement(LiteXMLDocument.INSTANTIATOR, MimeMediaType.XML_DEFAULTENCODING);
} catch (Throwable everything) {
everything.printStackTrace();
fail("Caught an unexpected exception - " + everything.toString());
}
}
public void testDOMXMLStructuredDoc() {
StructuredDocumentFactory.Instantiator domInstantiator = null;
try {
domInstantiator = (StructuredDocumentFactory.Instantiator) Class.forName("net.jxta.impl.document.DOMXMLDocument").getField("INSTANTIATOR").get(
null);
} catch (ClassNotFoundException noDOM) {
;
} catch (NoSuchFieldException noDOM) {
;
} catch (IllegalAccessException noDOM) {
;
}
try {
if (null != domInstantiator) {
_test(domInstantiator, MimeMediaType.XML_DEFAULTENCODING);
_testConstructors(domInstantiator, MimeMediaType.XML_DEFAULTENCODING);
_testAttributesSolo(domInstantiator, MimeMediaType.XML_DEFAULTENCODING);
}
} catch (Throwable everything) {
everything.printStackTrace();
fail("Caught an unexpected exception - " + everything.toString());
}
}
public void testPlainTextDoc() {
try {
_test(PlainTextDocument.INSTANTIATOR, MimeMediaType.TEXT_DEFAULTENCODING);
_testConstructors(PlainTextDocument.INSTANTIATOR, MimeMediaType.TEXT_DEFAULTENCODING);
_testAttributesSolo(PlainTextDocument.INSTANTIATOR, MimeMediaType.TEXT_DEFAULTENCODING);
} catch (Throwable everything) {
everything.printStackTrace();
fail("Caught an unexpected exception - " + everything.toString());
}
}
public void testExtensionMapping() {
MimeMediaType refMime = new MimeMediaType("Text/Xml");
String refExt = "xml";
String ext = StructuredDocumentFactory.getFileExtensionForMimeType(refMime);
MimeMediaType mime = StructuredDocumentFactory.getMimeTypeForFileExtension(ext);
assertTrue("mime type was not the same after reflex mapping", refMime.equals(mime));
assertTrue("extension was not the same after reflex mapping", refExt.equals(ext));
}
public void testIssue102() {
String WORKS = "<xml><stooges>Moe, Larry, AAʚ& Curly</stooges></xml>";
String DOES_NOT_WORK = "<xml><stooges>Moe, Larry, & Joe</stooges></xml>";
LiteXMLBug works = new LiteXMLBug(WORKS);
LiteXMLBug doesNotWork = new LiteXMLBug(DOES_NOT_WORK);
}
public void testIssue1282() {
try {
// create document
MimeMediaType mime = new MimeMediaType("text/xml");
XMLDocument document = (XMLDocument) LiteXMLDocument.INSTANTIATOR.newInstance(mime, "items");
for (int i = 0; i < 10; i++) {
XMLElement testElem = document.createElement("item");
document.appendChild(testElem);
testElem.addAttribute("name", "n" + i);
if (i == 3) {
for (int j = 0; j < 2; j++) {
XMLElement childElem = document.createElement("item");
testElem.appendChild(childElem);
childElem.addAttribute("name", "ch" + j);
}
}
}
// Serialize the message
ByteArrayOutputStream out = new ByteArrayOutputStream();
document.sendToStream(out);
InputStream is = new ByteArrayInputStream(out.toByteArray());
XMLDocument document2 = (XMLDocument) StructuredDocumentFactory.newStructuredDocument(mime, is);
Enumeration<XMLElement> eachOrig = document.getChildren();
Enumeration<XMLElement> eachNew = document2.getChildren();
while (eachOrig.hasMoreElements()) {
if (!eachNew.hasMoreElements()) {
fail("Enumeration did not end at same time.");
}
XMLElement anOrig = eachOrig.nextElement();
XMLElement aNew = eachNew.nextElement();
assertEquals("Elements names should be equivalent", aNew.getKey(), anOrig.getKey());
assertEquals("Elements values should be equivalent", aNew.getValue(), anOrig.getValue());
Attribute anOrigName = anOrig.getAttribute("name");
Attribute aNewName = aNew.getAttribute("name");
assertEquals("Element attribute name should be equivalent", anOrigName.getValue(), aNewName.getValue());
}
if (eachNew.hasMoreElements()) {
fail("Enumeration did not end at same time.");
}
} catch (Throwable everything) {
everything.printStackTrace();
fail("Caught an unexpected exception - " + everything.getMessage());
}
}
public void testIssue1372() {
XMLDocument document = null;
XMLDocument document2 = null;
try {
for (int depth = 1; depth <= 10; depth++) {
// create document
document = (XMLDocument) LiteXMLDocument.INSTANTIATOR.newInstance(MimeMediaType.XML_DEFAULTENCODING, "items");
for (int elemCount = 1; elemCount <= 2; elemCount++) {
XMLElement parentElem = document;
for (int layer = 1; layer <= depth; layer++) {
XMLElement testElem = document.createElement("item");
parentElem.appendChild(testElem);
testElem.addAttribute("name", depth + "-" + elemCount + ":" + layer);
parentElem = testElem;
}
}
// Serialize the message
StringWriter out = new StringWriter();
document.sendToWriter(out);
Reader is = new StringReader(out.toString());
document2 = (XMLDocument) StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XML_DEFAULTENCODING, is);
Enumeration<Element> eachOrig = document.getChildren();
Enumeration<Element> eachNew = document2.getChildren();
// FIXME 20050607 bondolo comparison doesn't recurse.
while (eachOrig.hasMoreElements()) {
if (!eachNew.hasMoreElements()) {
fail("Enumeration did not end at same time.");
}
XMLElement anOrig = (XMLElement) eachOrig.nextElement();
XMLElement aNew = (XMLElement) eachNew.nextElement();
assertEquals("Elements names should be equivalent", aNew.getKey(), anOrig.getKey());
assertEquals("Elements values should be equivalent", aNew.getValue(), anOrig.getValue());
Attribute anOrigName = anOrig.getAttribute("name");
Attribute aNewName = aNew.getAttribute("name");
assertEquals("Element attribute name should be equivalent", anOrigName.getValue(), aNewName.getValue());
}
if (eachNew.hasMoreElements()) {
fail("Enumeration did not end at same time.");
}
}
} catch (Throwable everything) {
System.err.flush();
System.out.flush();
everything.printStackTrace(System.err);
fail("Caught an unexpected exception - " + everything.getMessage());
}
}
public void testIssue13XX() {
XMLDocument document = null;
try {
Reader is = new StringReader(badlittleimpl);
document = (XMLDocument) StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XML_DEFAULTENCODING, is);
System.err.println(document);
} catch (Throwable everything) {
System.err.flush();
System.out.flush();
everything.printStackTrace(System.err);
fail("Caught an unexpected exception - " + everything.getMessage());
}
}
public void testIssue15() {
XMLDocument document = null;
try {
Reader is = new StringReader(badInclusion);
document = (XMLDocument) StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XML_DEFAULTENCODING, is);
System.err.println(document);
} catch (Throwable everything) {
System.err.flush();
System.out.flush();
everything.printStackTrace(System.err);
fail("Caught an unexpected exception - " + everything.getMessage());
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
junit.textui.TestRunner.run(suite());
System.err.flush();
System.out.flush();
}
}