001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: /*
043: * XMLModelTest.java
044: * JUnit based test
045: *
046: * Created on August 5, 2005, 12:13 PM
047: */
048: package org.netbeans.modules.xml.xdm;
049:
050: import java.beans.PropertyChangeListener;
051: import java.lang.management.ManagementFactory;
052: import java.lang.management.MemoryUsage;
053: import java.util.List;
054: import javax.swing.undo.UndoManager;
055: import junit.framework.*;
056: import org.netbeans.modules.xml.xam.ModelSource;
057: import org.netbeans.modules.xml.xdm.nodes.*;
058: import org.netbeans.modules.xml.xdm.visitor.PathFromRootVisitor;
059: import org.netbeans.modules.xml.xdm.visitor.FlushVisitor;
060: import org.openide.util.Lookup;
061: import org.openide.util.lookup.Lookups;
062: import org.w3c.dom.NodeList;
063:
064: /**
065: *
066: * @author Administrator
067: */
068: public class XDMModelTest extends TestCase {
069:
070: public XDMModelTest(String testName) {
071: super (testName);
072: }
073:
074: public static Test suite() {
075: TestSuite suite = new TestSuite();
076: suite.addTest(new XDMModelTest("testAdd"));
077: suite.addTest(new XDMModelTest("testAddNegative"));
078: suite.addTest(new XDMModelTest("testAddToSelfClosing"));
079: suite.addTest(new XDMModelTest("testAppend"));
080: suite.addTest(new XDMModelTest("testDelete"));
081: suite.addTest(new XDMModelTest("testFlush"));
082: suite.addTest(new XDMModelTest("testModify"));
083: suite.addTest(new XDMModelTest("testModifyNegative"));
084: suite.addTest(new XDMModelTest("testSyncAndNamespace"));
085: suite.addTest(new XDMModelTest("testSyncToEmptyRoot"));
086: suite.addTest(new XDMModelTest("testXDMModelSize"));
087: return suite;
088: }
089:
090: public void testAddNegative() throws Exception {
091: // verify that a node which is already in the tree cannot be added
092: Node company = (Node) model.getDocument().getChildNodes().item(
093: 0);
094: Node employee = (Node) company.getChildNodes().item(1);
095: try {
096: model.add(company, employee, 0);
097: fail("adding a node already in the tree should throw exception");
098: } catch (IllegalArgumentException iae) {
099:
100: }
101: }
102:
103: public void testModifyNegative() throws Exception {
104: // verify that a node which is already in the tree cannot be added
105: Node company = (Node) model.getDocument().getChildNodes().item(
106: 0);
107: Node employee = (Node) company.getChildNodes().item(1);
108: try {
109: model.modify(employee, employee);
110: fail("modifying a node already in the tree should throw exception");
111: } catch (IllegalArgumentException iae) {
112:
113: }
114:
115: // now try to substitute a different node
116: try {
117: Element e = (Element) model.getDocument().createElement("");
118: model.modify(employee, e);
119: fail("attempting to modify a node with a non equal node should throw exception");
120: } catch (IllegalArgumentException iae) {
121:
122: }
123: }
124:
125: /**
126: * Test of add method, of class xml.nodes.XMLModel.
127: */
128: public void testAdd() {
129: Document original = model.getDocument();
130: um.setLimit(10);
131: model.addUndoableEditListener(um);
132: FlushVisitor fv = new FlushVisitor();
133: String originalText = fv.flushModel(original);
134: // Expected model
135: // Document
136: // Element -- company
137: // Element -- employee
138: // Attribute -- ssn xx-xx-xxxx
139: // Attribute -- id
140: // Attribute -- phone
141: // Text -- Vidhya
142: // End Element
143: // End Element
144:
145: // first add another child element
146: Node company = (Node) model.getDocument().getChildNodes().item(
147: 0);
148: Node employee = (Node) company.getChildNodes().item(1);
149: Element customer = (Element) model.getDocument().createElement(
150: "customer");
151:
152: TestListener tl = new TestListener();
153: model.addPropertyChangeListener(tl);
154: model.add(employee, customer, 0);
155:
156: String modifiedText = fv.flushModel(model.getDocument());
157: assertNotSame(
158: "text should have been modified to add new attribute",
159: originalText, modifiedText);
160: assertTrue("only one event should be fired "
161: + tl.getEventsFired(), tl.getEventsFired() == 1);
162: assertEquals("event should be modified", model.PROP_ADDED, tl
163: .getLastEventName());
164:
165: PathFromRootVisitor pfrv = new PathFromRootVisitor();
166: assertNotNull("customer should now be in the tree", pfrv
167: .findPath(model.getDocument(), customer));
168:
169: // TODO verify some of the nodes which should not have been cloned
170:
171: // now verify that the new child element is added in right location
172: company = (Node) model.getDocument().getChildNodes().item(0);
173: employee = (Node) company.getChildNodes().item(1);
174: Element customer2 = (Element) employee.getChildNodes().item(0);
175:
176: assertEquals("expected name was not set", customer2
177: .getLocalName(), customer.getLocalName());
178:
179: // verify undo / redo
180: assertTrue("undo manager should have one event", um.canUndo());
181: assertFalse("undo manager should not allow redo", um.canRedo());
182:
183: Document newD = model.getDocument();
184: um.undo();
185: assertSame("model not original tree", model.getDocument(),
186: original);
187: um.redo();
188: assertSame("model not new tree", model.getDocument(), newD);
189:
190: //Adding a brand new element for testing
191: company = (Node) model.getDocument().getChildNodes().item(0);
192: Element emp = (Element) model.getDocument().createElement(
193: "employee");
194:
195: tl.resetFiredEvents();
196: model.add(company, emp, 0);
197:
198: assertTrue("only one event should be fired "
199: + tl.getEventsFired(), tl.getEventsFired() == 1);
200: assertEquals("event should be added", model.PROP_ADDED, tl
201: .getLastEventName());
202:
203: pfrv = new PathFromRootVisitor();
204: assertNotNull("new employee should now be in the tree", pfrv
205: .findPath(model.getDocument(), emp));
206: }
207:
208: public void testAddToSelfClosing() throws Exception {
209: sd = Util.getResourceAsDocument("selfClosing.xml");
210: Lookup lookup = Lookups.singleton(sd);
211: ModelSource ms = new ModelSource(lookup, true);
212: model = new XDMModel(ms);
213: model.sync();
214:
215: Document original = model.getDocument();
216: //Adding a brand new element for testing
217: Node company = (Node) model.getDocument().getChildNodes().item(
218: 0);
219: Element emp = (Element) model.getDocument().createElement(
220: "employee");
221:
222: model.add(company, emp, 0);
223: model.flush();
224: model.sync();
225: company = (Node) model.getDocument().getChildNodes().item(0);
226: emp = (Element) company.getFirstChild();
227: assertEquals("employee is not local name", emp.getLocalName(),
228: "employee");
229: List<Token> tokens = emp.getTokens();
230: int endTokenCount = 0;
231: for (Token t : tokens) {
232: if (t.getType().equals(TokenType.TOKEN_ELEMENT_END_TAG)) {
233: endTokenCount++;
234: }
235: }
236: assertEquals(
237: "employee should be created using self-closing tag", 1,
238: endTokenCount);
239: }
240:
241: /**
242: * Test of append method, of class xml.nodes.XMLModel.
243: */
244: public void testAppend() {
245: Document original = model.getDocument();
246: um.setLimit(10);
247: model.addUndoableEditListener(um);
248: // Expected model
249: // Document
250: // Element -- company
251: // Element -- employee
252: // Attribute -- ssn xx-xx-xxxx
253: // Attribute -- id
254: // Attribute -- phone
255: // Text -- Vidhya
256: // End Element
257: // End Element
258:
259: // first append another child element
260: Node company = (Node) model.getDocument().getChildNodes().item(
261: 0);
262: Node employee = (Node) company.getChildNodes().item(1);
263: Element customer = (Element) model.getDocument().createElement(
264: "customer");
265:
266: TestListener tl = new TestListener();
267: model.addPropertyChangeListener(tl);
268: model.append(employee, customer);
269:
270: assertTrue("only one event should be fired "
271: + tl.getEventsFired(), tl.getEventsFired() == 1);
272: assertEquals("event should be modified", model.PROP_ADDED, tl
273: .getLastEventName());
274:
275: PathFromRootVisitor pfrv = new PathFromRootVisitor();
276: assertNotNull("customer should now be in the tree", pfrv
277: .findPath(model.getDocument(), customer));
278:
279: // TODO verify some of the nodes which should not have been cloned
280:
281: // now verify that the new child element is added in right location (at the end)
282: company = (Node) model.getDocument().getChildNodes().item(0);
283: employee = (Node) company.getChildNodes().item(1);
284: Element customer2 = (Element) employee.getChildNodes().item(
285: employee.getChildNodes().getLength() - 1);
286:
287: assertEquals("expected name was not set", customer2
288: .getLocalName(), customer.getLocalName());
289:
290: //Appending a brand new element with attributes
291: company = (Node) model.getDocument().getChildNodes().item(0);
292: Element emp2 = (Element) model.getDocument().createElement(
293: "employee");
294: Attribute att = (Attribute) model.getDocument()
295: .createAttribute("id2");
296: att.setValue("987");
297: emp2.setAttributeNode(att);
298:
299: tl.resetFiredEvents();
300: model.append(company, emp2);
301:
302: assertTrue("only one event should be fired "
303: + tl.getEventsFired(), tl.getEventsFired() == 1);
304: assertEquals("event should be added", model.PROP_ADDED, tl
305: .getLastEventName());
306:
307: pfrv = new PathFromRootVisitor();
308: assertNotNull("new employee should now be in the tree", pfrv
309: .findPath(model.getDocument(), emp2));
310: }
311:
312: /**
313: * Test of delete method, of class xml.nodes.XMLTreeGenerator.
314: */
315: public void testDelete() {
316: Document original = model.getDocument();
317: um.setLimit(10);
318: model.addUndoableEditListener(um);
319: // Expected model
320: // Document
321: // Element -- company
322: // Element -- employee
323: // Attribute -- ssn xx-xx-xxxx
324: // Attribute -- id
325: // Attribute -- phone
326: // Text -- Vidhya
327: // End Element
328: // End Element
329:
330: // first get text element
331: Node company = (Node) model.getDocument().getChildNodes().item(
332: 0);
333: Node employee = (Node) company.getChildNodes().item(1);
334: Text txt = (Text) employee.getChildNodes().item(0);
335:
336: TestListener tl = new TestListener();
337: model.addPropertyChangeListener(tl);
338: model.delete(txt);
339:
340: assertTrue("only one event should be fired "
341: + tl.getEventsFired(), tl.getEventsFired() == 1);
342: assertEquals("event should be modified", model.PROP_DELETED, tl
343: .getLastEventName());
344:
345: PathFromRootVisitor pfrv = new PathFromRootVisitor();
346: assertNull("txt should no longer be in the tree", pfrv
347: .findPath(model.getDocument(), txt));
348:
349: // TODO verify some of the nodes which should not have been cloned
350:
351: // verify undo / redo
352: assertTrue("undo manager should have one event", um.canUndo());
353: assertFalse("undo manager should not allow redo", um.canRedo());
354:
355: Document newD = model.getDocument();
356: um.undo();
357: assertSame("model not original tree", model.getDocument(),
358: original);
359: um.redo();
360: assertSame("model not new tree", model.getDocument(), newD);
361: }
362:
363: /**
364: * Test of modify method, of class xml.nodes.XMLTreeGenerator.
365: */
366: public void testModify() throws Exception {
367: Document original = model.getDocument();
368: um.setLimit(10);
369: model.addUndoableEditListener(um);
370: // Expected model
371: // Document
372: // Element -- company
373: // Element -- employee
374: // Attribute -- ssn xx-xx-xxxx
375: // Attribute -- id
376: // Attribute -- phone
377: // Text -- Vidhya
378: // End Element
379: // End Element
380:
381: // first get employee element
382: Node company = (Node) model.getDocument().getChildNodes().item(
383: 0);
384: Element employee = (Element) company.getChildNodes().item(1);
385: Element employee2 = (Element) employee.cloneNode(true);
386: String attrName = "sss";
387: String attrValue0 = employee.getAttribute(attrName);
388: String attrValue = "111-11-2222";
389: employee2.setAttribute(attrName, attrValue);
390: TestListener tl = new TestListener();
391:
392: model.addPropertyChangeListener(tl);
393: model.modify(employee, employee2);
394:
395: assertTrue("only one event should be fired", tl
396: .getEventsFired() == 1);
397: assertEquals("event should be modified", model.PROP_MODIFIED,
398: tl.getLastEventName());
399:
400: PathFromRootVisitor pfrv = new PathFromRootVisitor();
401: assertNotSame("original company should not be in tree",
402: company, pfrv.findPath(model.getDocument(), company)
403: .get(0));
404: assertNull("original employee should not be tree", pfrv
405: .findPath(model.getDocument(), employee));
406:
407: // now verify that the new employee is what we set
408: company = (Node) model.getDocument().getChildNodes().item(0);
409: employee = (Element) company.getChildNodes().item(1);
410: assertEquals("expected name was not set", employee
411: .getAttribute(attrName), attrValue);
412:
413: // verify undo / redo
414: assertTrue("undo manager should have one event", um.canUndo());
415: assertFalse("undo manager should not allow redo", um.canRedo());
416:
417: Document newD = model.getDocument();
418: um.undo();
419: assertSame("model not original tree", model.getDocument(),
420: original);
421: company = (Node) model.getDocument().getChildNodes().item(0);
422: employee = (Element) company.getChildNodes().item(1);
423: assertEquals("expected name was not set", attrValue0, employee
424: .getAttribute(attrName));
425:
426: um.redo();
427: assertSame("model not new tree", model.getDocument(), newD);
428: company = (Node) model.getDocument().getChildNodes().item(0);
429: employee = (Element) company.getChildNodes().item(1);
430: assertEquals("expected name was not set", attrValue, employee
431: .getAttribute(attrName));
432: }
433:
434: public void testFlush() throws Exception {
435: Document original = model.getDocument();
436: um.setLimit(10);
437: model.addUndoableEditListener(um);
438: String origContent = sd.getText(0, sd.getLength());
439: model.flush();
440: String flushContent = sd.getText(0, sd.getLength());
441: assertEquals("expected same content after flush", origContent,
442: flushContent);
443:
444: Document oldDoc = model.getDocument();
445: assertSame("Models before and after flush are same ", original,
446: oldDoc);
447:
448: //Force sync to make sure the new model is the same as the current one
449: model.sync();
450:
451: Document newDoc = model.getDocument();
452: assertSame("Models before and after flush/sync are same ",
453: oldDoc, newDoc);
454: //TODO should have a good way of testing old and new models.
455: }
456:
457: public void testSyncAndNamespace() throws Exception {
458: javax.swing.text.Document swdoc = Util
459: .getResourceAsDocument("TestSyncNamespace.wsdl");
460: XDMModel m = Util.loadXDMModel(swdoc);
461: Element root = (Element) m.getCurrentDocument()
462: .getDocumentElement();
463: NodeList nl = root.getChildNodes();
464: Element messageE = null;
465: for (int i = 0; i < nl.getLength(); i++) {
466: if (nl.item(i) instanceof Element) {
467: Element e = (Element) nl.item(i);
468: if (e.getLocalName().equals("message")) {
469: messageE = e;
470: }
471: }
472: }
473: assertNotNull(messageE);
474: assertEquals("http://schemas.xmlsoap.org/wsdl/", messageE
475: .getNamespaceURI());
476:
477: Util.setDocumentContentTo(swdoc, "TestSyncNamespace_1.wsdl");
478: m.sync();
479:
480: nl = messageE.getChildNodes();
481: Element partE = null;
482: for (int i = 0; i < nl.getLength(); i++) {
483: if (nl.item(i) instanceof Element) {
484: Element e = (Element) nl.item(i);
485: if (e.getLocalName().equals("part")) {
486: partE = e;
487: }
488: }
489: }
490: assertNotNull(partE);
491: assertEquals("http://schemas.xmlsoap.org/wsdl/", messageE
492: .getNamespaceURI());
493: assertEquals("http://schemas.xmlsoap.org/wsdl/", partE
494: .getNamespaceURI());
495: }
496:
497: public void testSyncToEmptyRoot() throws Exception {
498: javax.swing.text.Document swdoc = Util
499: .getResourceAsDocument("resources/test1.xml");
500: XDMModel m = Util.loadXDMModel(swdoc);
501: Document old = m.getCurrentDocument();
502: Element root = (Element) m.getCurrentDocument()
503: .getDocumentElement();
504: assertEquals(7, root.getChildNodes().getLength());
505: Util.setDocumentContentTo(swdoc, "resources/Empty.xml");
506: m.prepareSync();
507: m.sync();
508: assertNotSame(m.getCurrentDocument(), old);
509: root = (Element) m.getCurrentDocument().getDocumentElement();
510: assertEquals(1, root.getChildNodes().getLength());
511: }
512:
513: static class TestListener implements PropertyChangeListener {
514: private String eventName;
515: private int count = 0;
516:
517: public void propertyChange(java.beans.PropertyChangeEvent evt) {
518: eventName = evt.getPropertyName();
519: count++;
520: }
521:
522: public int getEventsFired() {
523: return count;
524: }
525:
526: public String getLastEventName() {
527: return eventName;
528: }
529:
530: public void resetFiredEvents() {
531: count = 0;
532: }
533: }
534:
535: public void testXDMModelSize() throws Exception {
536: System.out.println("XDM Mem usage");
537: MemoryUsage usage = ManagementFactory.getMemoryMXBean()
538: .getHeapMemoryUsage();
539: long mem0 = usage.getUsed();
540: javax.swing.text.Document swdoc = Util
541: .getResourceAsDocument("resources/fields.xsd");
542: usage = ManagementFactory.getMemoryMXBean()
543: .getHeapMemoryUsage();
544: long mem1 = usage.getUsed();
545:
546: long memuse = mem1 - mem0;
547:
548: System.out.println("Document creation = " + memuse + " bytes");
549:
550: Lookup lookup = Lookups.singleton(swdoc);
551: usage = ManagementFactory.getMemoryMXBean()
552: .getHeapMemoryUsage();
553: long mem2 = usage.getUsed();
554: ModelSource ms = new ModelSource(lookup, true);
555: usage = ManagementFactory.getMemoryMXBean()
556: .getHeapMemoryUsage();
557: long mem3 = usage.getUsed();
558: memuse = mem3 - mem2;
559:
560: System.out.println("Model source creation = " + memuse
561: + " bytes");
562:
563: XDMModel m = new XDMModel(ms);
564: m.sync();
565: usage = ManagementFactory.getMemoryMXBean()
566: .getHeapMemoryUsage();
567: long mem4 = usage.getUsed();
568: memuse = mem4 - mem3;
569: System.out.println("XDM creation = " + memuse + " bytes");
570: //System.out.println("Time taken to create XDM model: " + (endTime - startTime));
571:
572: }
573:
574: protected void setUp() throws Exception {
575: um = new UndoManager();
576: sd = Util.getResourceAsDocument("test.xml");
577: Lookup lookup = Lookups.singleton(sd);
578: ModelSource ms = new ModelSource(lookup, true);
579: model = new XDMModel(ms);
580: model.sync();
581: }
582:
583: private javax.swing.text.Document sd;
584: private XDMModel model;
585: private UndoManager um;
586: }
|