/* * 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 dom.range; import java.io.StringReader; import org.apache.xerces.dom.DocumentImpl; import org.apache.xerces.parsers.DOMParser; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.DocumentFragment; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.ranges.Range; import org.xml.sax.InputSource; import dom.Writer; /** * This RangeTest tests all of the cases delineated as examples * in the DOM Level 2 Range specification, and a few others. *

These do not by any means completely test the API and * corner cases. * * @version $Id$ */ public class Test { static final boolean DEBUG = false; static boolean fStdOut = false; static final String [] tests = { "ABCDCD", "ABCDE", "XYZWQ", "ABCD", ""+ ""+ "" }; static final String [] deleteResult = { "ACD", "ABE", "XWQ", "AD", "" }; static final String [] extractResult = { "BCD", "CD", "YZ", "BC", ""+ "" }; static final String INSERT="***"; static final String [] insertResult = { "A"+INSERT+"BCDCD", "AB"+INSERT+"CDE", "X"+INSERT+"YZWQ", "A"+INSERT+"BCD", ""+INSERT+""+ "" }; static final String SURROUND="SURROUND"; static final String [] surroundResult = { "A<"+SURROUND+">BCDCD", "AB<"+SURROUND+">CDE", "X<"+SURROUND+">YZWQ", "AB<"+SURROUND+">CD", ""+ "<"+SURROUND+">"+ "" }; static final String [] rangeDelete = { "

Abcd efgh The Range ijkl

", "

Abcd efgh The Range ijkl

", "

ABCD efgh The Range ijkl

", "

Abcd efgh The Range ijkl

", "

Abcd efgh The Range ijkl

" }; // static final String [] rangeDeleteResult = { "

Abcd ^Range ijkl

", "

Abcd ^kl

", "

ABCD ^ange ijkl

", "

Abcd ^he Range ijkl

", "

Abcd ^kl

" }; static final String INSERT2="

Abcd efgh XY blah ijkl

"; static final String INSERTED_TEXT = "INSERTED TEXT"; static final String [] rangeInsertResult = { "

Abcd efgh INSERTED TEXTXY blah ijkl

", "

Abcd efgh XINSERTED TEXTY blah ijkl

", "

Abcd efgh XYINSERTED TEXT blah ijkl

", "

Abcd efgh XY blahINSERTED TEXT ijkl

" }; public static void main(String args[]) { // is there anything to do? if ( args.length == 0 ) { printUsage(); System.exit(1); } if (args.length > 1) { if (args[1].equals("yes")){ fStdOut = true; } } new Test(args[0]); } /** Prints the usage. */ private static void printUsage() { System.err.println("usage: java dom.range.Test (option) (stdout)"); System.err.println(); System.err.println("options:"); System.err.println(" all all tests"); System.err.println(" delete delete test"); System.err.println(" extract extract test"); System.err.println(" clone clone test"); System.err.println(" insert insert test"); System.err.println(" surround surround test"); System.err.println(" insert2 insert mutation test"); System.err.println(" delete2 delete mutation test"); System.err.println("stdout:"); System.err.println(" yes print to standard output"); System.err.println(" no don't print any messages to standard output [default]"); } // printUsage() public Test(String arg) { if (arg.equals("all")) { boolean all = false; all = performTest("delete"); all = performTest("extract")&&all; all = performTest("clone")&&all; all = performTest("insert")&&all; all = performTest("surround")&&all; all = performTest("insert2")&&all; all = performTest("delete2")&&all; if (all) { System.out.println("Done."); } else { System.out.println("*** ONE OR MORE TESTS FAILED! ***"); System.exit(1); } } else { performTest(arg); } } public boolean performTest(String arg) { boolean passed = true; try { Writer writer = new Writer(false); DOMParser parser = new DOMParser(); if (!arg.equals("delete2") && !arg.equals("insert2")) { if (fStdOut) System.out.println("\n*************** Test == "+arg+" ***************"); for (int i = 0; i < tests.length; i++) { if (fStdOut) System.out.println("\n\nTest["+i+"]"); if (fStdOut) System.out.println("\nBefore "+arg+": document="+tests[i]+":"); parser.parse(new InputSource(new StringReader(tests[i]))); DocumentImpl document = (DocumentImpl)parser.getDocument(); Range range = document.createRange(); Node root = document.getDocumentElement(); boolean surround = false; Node surroundNode=document.createElement(SURROUND); if (arg.equals("surround")) { surround = true; } if (i == 0) { range.setStart(root.getFirstChild(), 1); range.setEndBefore(root.getLastChild()); if (surround) range.setEnd(root.getLastChild(),1); } else if (i == 1) { Node n1 = root.getFirstChild().getNextSibling(). getFirstChild(); range.setStart(n1, 1); range.setEnd(root.getLastChild(), 1); if (surround) range.setEnd(n1,2); } else if (i == 2) { range.setStart(root.getFirstChild(), 1); Node n2 = root.getFirstChild().getNextSibling().getFirstChild(); range.setEnd(n2, 1); if (surround) range.setEndBefore(root.getLastChild()); } else if (i == 3) { Node n3 = root.getFirstChild().getFirstChild(); range.setStart(n3, 1); range.setEnd(root.getLastChild().getFirstChild(), 1); if (surround) { range.selectNode(root.getFirstChild().getNextSibling()); } } else if (i == 4) { Node n4 = root.getFirstChild().getFirstChild().getNextSibling().getFirstChild(); range.setStartAfter(n4); range.setEndAfter(root.getLastChild().getFirstChild()); if (surround) { range.selectNodeContents(root.getFirstChild().getNextSibling()); } } if (fStdOut) System.out.println("range.toString="+range.toString()); DocumentFragment frag = null; if (arg.equals("surround")) { try { if (fStdOut) System.out.println("surroundNode="+surroundNode); range.surroundContents(surroundNode); } catch (org.w3c.dom.ranges.RangeException e) { if (fStdOut) System.out.println(e); } String result = toString(document); if (fStdOut) System.out.println("After surround: document="+result+":"); if (!result.equals(surroundResult[i])) { if (fStdOut) System.out.println("Should be: document="+surroundResult[i]+":"); passed = false; if (fStdOut) System.out.println("Test FAILED!"); if (fStdOut) System.out.println("*** Surround document Test["+i+"] FAILED!"); } } if (arg.equals("insert")) { range.insertNode(document.createTextNode(INSERT)); String result = toString(document); if (fStdOut) System.out.println("After insert: document="+result+":"); if (!result.equals(insertResult[i])) { if (fStdOut) System.out.println("Should be: document="+insertResult[i]+":"); passed = false; if (fStdOut) System.out.println("Test FAILED!"); if (fStdOut) System.out.println("*** Insert document Test["+i+"] FAILED!"); } } else if (arg.equals("delete")) { range.deleteContents(); String result = toString(document); if (fStdOut) System.out.println("After delete:"+result+":"); if (!result.equals(deleteResult[i])) { if (fStdOut) System.out.println("Should be: document="+deleteResult[i]+":"); passed = false; if (fStdOut) System.out.println("Test FAILED!"); if (fStdOut) System.out.println("*** Delete document Test["+i+"] FAILED!"); } } else if (arg.equals("extract")) { frag = range.extractContents(); //range.insertNode(document.createTextNode("^")); String result = toString(document); if (fStdOut) System.out.println("After extract: document="+result+":"); if (!result.equals(deleteResult[i])) { if (fStdOut) System.out.println("Should be: document="+deleteResult[i]+":"); passed = false; if (fStdOut) System.out.println("*** Extract document Test["+i+"] FAILED!"); } String fragResult = toString(frag); if (fStdOut) System.out.println("After extract: fragment="+fragResult+":"); if (!fragResult.equals(extractResult[i])) { if (fStdOut) System.out.println("Should be: fragment="+extractResult[i]+":"); passed = false; if (fStdOut) System.out.println("*** Extract Fragment Test["+i+"] FAILED!"); } } else if (arg.equals("clone")) { frag = range.cloneContents(); String fragResult = toString(frag); if (fStdOut) System.out.println("After clone: fragment="+fragResult); if (!fragResult.equals(extractResult[i])) { if (fStdOut) System.out.println("Should be: fragment="+extractResult[i]+":"); passed = false; if (fStdOut) System.out.println("*** Clone Fragment Test["+i+"] FAILED!"); } } } } else if (arg.equals("insert2")) { if (fStdOut) System.out.println("\n*************** Test == "+arg+" ***************"); for (int i = 0; i < 4; i++) { if (fStdOut) System.out.println("\n\nTest["+i+"]"); if (fStdOut) System.out.println("\nBefore "+arg+": document="+INSERT2+":"); parser.parse(new InputSource(new StringReader(INSERT2))); DocumentImpl document = (DocumentImpl)parser.getDocument(); Node root = document.getDocumentElement(); Range range = document.createRange(); range.setStart(root.getFirstChild(),11); range.setEnd(root.getFirstChild(),18); Range rangei = document.createRange(); if (i == 0) { rangei.setStart(root.getFirstChild(), 10); rangei.setEnd(root.getFirstChild(), 10); } if (i == 1) { rangei.setStart(root.getFirstChild(), 11); rangei.setEnd(root.getFirstChild(), 11); } if (i == 2) { rangei.setStart(root.getFirstChild(), 12); rangei.setEnd(root.getFirstChild(), 12); } if (i == 3) { rangei.setStart(root.getFirstChild(), 17); rangei.setEnd(root.getFirstChild(), 17); } //if (fStdOut) System.out.println("range: start1=="+range.getStartContainer()); //root.insertBefore(document.createTextNode("YES!"), root.getFirstChild()); //if (fStdOut) System.out.println("range: start2=="+range.getStartContainer()); if (DEBUG) if (fStdOut) System.out.println("before insert start="+range.getStartOffset()); if (DEBUG) if (fStdOut) System.out.println("before insert end="+range.getEndOffset()); rangei.insertNode(document.createTextNode(INSERTED_TEXT)); if (DEBUG) if (fStdOut) System.out.println("after insert start="+range.getStartOffset()); if (DEBUG) if (fStdOut) System.out.println("after insert end="+range.getEndOffset()); String result = toString(document); if (fStdOut) System.out.println("After insert2: document="+result+":"); if (!result.equals(rangeInsertResult[i])) { if (fStdOut) System.out.println("Should be: document="+rangeInsertResult[i]+":"); passed = false; if (fStdOut) System.out.println("Test FAILED!"); if (fStdOut) System.out.println("*** Delete Ranges document Test["+i+"] FAILED!"); } } } else if (arg.equals("delete2")) { // // Range Deletion, acting upon another range. // if (fStdOut) System.out.println("\n*************** Test == "+arg+" ***************"); for (int i = 0; i < rangeDelete.length; i++) { if (fStdOut) System.out.println("\n\nTest["+i+"]"); if (fStdOut) System.out.println("\nBefore "+arg+": document="+rangeDelete[i]+":"); parser.parse(new InputSource(new StringReader(rangeDelete[i]))); DocumentImpl document = (DocumentImpl)parser.getDocument(); Range range = document.createRange(); Range ranged = document.createRange(); Node root = document.getDocumentElement(); boolean surround = false; Node surroundNode=document.createElement(SURROUND); if (arg.equals("surround")) { surround = true; } if (i == 0) { ranged.setStart(root.getFirstChild(), 5); ranged.setEnd(root.getFirstChild(), 14); range.setStart(root.getFirstChild(), 11); range.setEnd(root.getFirstChild(), 19); } else if (i == 1) { ranged.setStart(root.getFirstChild(), 5); ranged.setEnd(root.getFirstChild(), 22); range.setStart(root.getFirstChild(), 11); range.setEnd(root.getFirstChild(), 21); } else if (i == 2) { ranged.setStart(root.getFirstChild(), 5); ranged.setEnd(root.getFirstChild().getNextSibling() .getFirstChild(), 1); range.setStart(root.getFirstChild(), 11); range.setEndAfter(root.getFirstChild().getNextSibling() .getFirstChild()); } else if (i == 3) { ranged.setStart(root.getFirstChild(), 5); ranged.setEnd(root.getFirstChild(), 11); range.setStart(root.getFirstChild(), 11); range.setEnd(root.getFirstChild(), 21); } else if (i == 4) { ranged.selectNode(root.getFirstChild().getNextSibling()); range.setStart(root.getFirstChild().getNextSibling() .getFirstChild(), 6); range.setEnd(root.getFirstChild().getNextSibling() .getFirstChild(), 15); } DocumentFragment frag = null; if (arg.equals("delete2")) { if (DEBUG) { if (fStdOut) System.out.println("BEFORE deleteContents()"); if (fStdOut) System.out.println("ranged: startc="+ranged.getStartContainer()); if (fStdOut) System.out.println("ranged: starto="+ranged.getStartOffset()); if (fStdOut) System.out.println("ranged: endc="+ranged.getEndContainer()); if (fStdOut) System.out.println("ranged: endo="+ranged.getEndOffset()); if (fStdOut) System.out.println("range: startc="+range.getStartContainer()); if (fStdOut) System.out.println("range: starto="+range.getStartOffset()); if (fStdOut) System.out.println("range: endc="+range.getEndContainer()); if (fStdOut) System.out.println("range: endo="+range.getEndOffset()); } ranged.deleteContents(); String result = null; if (DEBUG) { if (fStdOut) System.out.println("AFTER deleteContents()"); result = toString(document); if (fStdOut) System.out.println("ranged: startc="+ranged.getStartContainer()); if (fStdOut) System.out.println("ranged: starto="+ranged.getStartOffset()); if (fStdOut) System.out.println("ranged: endc="+ranged.getEndContainer()); if (fStdOut) System.out.println("ranged: endo="+ranged.getEndOffset()); if (fStdOut) System.out.println("range: startc="+range.getStartContainer()); if (fStdOut) System.out.println("range: starto="+range.getStartOffset()); if (fStdOut) System.out.println("range: endc="+range.getEndContainer()); if (fStdOut) System.out.println("range: endo="+range.getEndOffset()); } ranged.insertNode(document.createTextNode("^")); result = toString(document); if (fStdOut) System.out.println("After delete2: document="+result+":"); if (!result.equals(rangeDeleteResult[i])) { if (fStdOut) System.out.println("Should be: document="+rangeDeleteResult[i]+":"); passed = false; if (fStdOut) System.out.println("Test FAILED!"); if (fStdOut) System.out.println("*** Delete Ranges document Test["+i+"] FAILED!"); } } } } } catch (org.xml.sax.SAXParseException spe) { passed = false; } catch (org.xml.sax.SAXException se) { if (se.getException() != null) se.getException().printStackTrace(System.err); else se.printStackTrace(System.err); passed = false; } catch (Exception e) { e.printStackTrace(System.err); passed = false; } if (!passed) if (fStdOut) System.out.println("*** The "+arg+" Test FAILED! ***"); return passed; } StringBuffer sb; boolean canonical = true; String toString(Node node) { sb = new StringBuffer(); return print(node); } /** Prints the specified node, recursively. */ public String print(Node node) { // is there anything to do? if ( node == null ) { return sb.toString(); } int type = node.getNodeType(); switch ( type ) { // print document case Node.DOCUMENT_NODE: { return print(((Document)node).getDocumentElement()); //out.flush(); //break; } // print element with attributes case Node.ELEMENT_NODE: { sb.append('<'); sb.append(node.getNodeName()); Attr attrs[] = sortAttributes(node.getAttributes()); for ( int i = 0; i < attrs.length; i++ ) { Attr attr = attrs[i]; sb.append(' '); sb.append(attr.getNodeName()); sb.append("=\""); sb.append(normalize(attr.getNodeValue())); sb.append('"'); } sb.append('>'); NodeList children = node.getChildNodes(); if ( children != null ) { int len = children.getLength(); for ( int i = 0; i < len; i++ ) { print(children.item(i)); } } break; } // handle entity reference nodes case Node.ENTITY_REFERENCE_NODE: { if ( canonical ) { NodeList children = node.getChildNodes(); if ( children != null ) { int len = children.getLength(); for ( int i = 0; i < len; i++ ) { print(children.item(i)); } } } else { sb.append('&'); sb.append(node.getNodeName()); sb.append(';'); } break; } // print cdata sections case Node.CDATA_SECTION_NODE: { if ( canonical ) { sb.append(normalize(node.getNodeValue())); } else { sb.append(""); } break; } // print text case Node.TEXT_NODE: { sb.append(normalize(node.getNodeValue())); break; } // print processing instruction case Node.PROCESSING_INSTRUCTION_NODE: { sb.append(" 0 ) { sb.append(' '); sb.append(data); } sb.append("?>"); break; } // handle entity reference nodes case Node.DOCUMENT_FRAGMENT_NODE: { NodeList children = node.getChildNodes(); if ( children != null ) { int len = children.getLength(); for ( int i = 0; i < len; i++ ) { print(children.item(i)); } } break; } } if ( type == Node.ELEMENT_NODE ) { sb.append("'); } return sb.toString(); } // print(Node) /** Returns a sorted list of attributes. */ protected Attr[] sortAttributes(NamedNodeMap attrs) { int len = (attrs != null) ? attrs.getLength() : 0; Attr array[] = new Attr[len]; for ( int i = 0; i < len; i++ ) { array[i] = (Attr)attrs.item(i); } for ( int i = 0; i < len - 1; i++ ) { String name = array[i].getNodeName(); int index = i; for ( int j = i + 1; j < len; j++ ) { String curName = array[j].getNodeName(); if ( curName.compareTo(name) < 0 ) { name = curName; index = j; } } if ( index != i ) { Attr temp = array[i]; array[i] = array[index]; array[index] = temp; } } return (array); } // sortAttributes(NamedNodeMap):Attr[] /** Normalizes the given string. */ protected String normalize(String s) { StringBuffer str = new StringBuffer(); int len = (s != null) ? s.length() : 0; for ( int i = 0; i < len; i++ ) { char ch = s.charAt(i); switch ( ch ) { case '<': { str.append("<"); break; } case '>': { str.append(">"); break; } case '&': { str.append("&"); break; } case '"': { str.append("""); break; } case '\r': case '\n': { if ( canonical ) { str.append("&#"); str.append(Integer.toString(ch)); str.append(';'); break; } // else, default append char } default: { str.append(ch); } } } return (str.toString()); } // normalize(String):String }