blob: a7e2d159a45764ddcba653a944fdf8638ae5e63e [file] [log] [blame]
/*
* 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.
*/
/*
* TestMerge - test the basic features.
*
*/
import org.netbeans.modules.schema2beans.*;
import java.beans.*;
import book.*;
public class TestMerge extends BaseTest {
public static void main(String[] argv) {
BaseTest o = new TestMerge();
if (argv.length > 0)
o.setDocumentDir(argv[0]);
try {
o.run();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
System.exit(0);
}
//
// This is the reference number for memory consumption for 50 clones
// (simply ran the test to get the number). We check against this number
// to make sure that any change in schema2beans does not introduce a
// significant increase of mem usage. (Note that sometimes JDK changes
// can change this number too.)
//
static float memUsageReference = 5226;
public class MyListener implements PropertyChangeListener {
GraphManager gm;
String listenerName;
Object oldValue;
Object newValue;
String propertyName;
Object source;
int index;
boolean mute;
boolean remove;
public MyListener(BaseBean bean) {
this.listenerName = bean.name();
gm = bean.graphManager();
this.remove = false;
this.mute = false;
out("new listener for " + this.listenerName);
}
public void reset() {
this.oldValue = null;
this.newValue = null;
this.propertyName = null;
this.source = null;
this.index = -1;
}
public void propertyChange(PropertyChangeEvent e) {
if (this.mute)
return;
String k;
this.oldValue = e.getOldValue();
this.newValue = e.getNewValue();
this.propertyName = e.getPropertyName();
this.source = e.getSource();
String n = this.propertyName;
this.index = gm.getPropertyIndex(n);
if (this.newValue == null)
k = "Rmv";
else
if (this.oldValue == null)
k = "Add";
else
k = "Chg";
out("<" + k + " Lnr:" + this.listenerName + " Evt:" + n +
" Src:" + this.source.getClass().getName() + ">");
if (remove) {
out("<" + gm.getPropertyName(n) + "[" + this.index +
"]" + " - Parent: " + gm.getPropertyParentName(n) + ">");
} else {
BaseBean propertyParent = gm.getPropertyParent(n);
String parentClassName = propertyParent == null ? "<no class>" : propertyParent.getClass().getName();
out("<" + gm.getPropertyName(n) + "[" + this.index +
"]" + " - Parent: " + gm.getPropertyParentName(n) +
"/" + parentClassName + ">");
}
//out("received " + this.oldValue + "/" + this.newValue + "/" +
// this.propertyName);
}
public void removeMode() {
this.remove = true;
}
public Object oldValue() {
return this.oldValue;
}
public String stringOldValue() {
if (this.oldValue == null)
return "<null>";
else
return this.oldValue.toString();
}
public Object newValue() {
return this.newValue;
}
public String stringNewValue() {
if (this.newValue == null)
return "<null>";
else
return this.newValue.toString();
}
public String name() {
return this.propertyName;
}
public void mute(boolean mute) {
this.mute = mute;
}
public String toString() {
return this.name() + " raised from source " +
this.source.getClass().getName();
}
}
private MyListener l1, l2, l3;
void mute(boolean mute) {
if (l1 != null)
l1.mute(mute);
if (l2 != null)
l2.mute(mute);
if (l3 != null)
l3.mute(mute);
}
public void run()
throws Exception {
Book b1, b2, b3;
this.readDocument("tm01_g1.xml");
out("creating the bean graph1");
b1 = Book.createGraph(doc);
this.readDocument("tm01_g1.xml");
out("creating the bean graph2");
b2 = Book.createGraph(doc);
l1 = new MyListener(b1);
b1.addPropertyChangeListener(l1);
// b2 should never change, so we should never receive anything
// on this listener
l2 = new MyListener(b2);
b2.addPropertyChangeListener(l2);
//
// Merge two identical graphs
//
setTest("Merge(Update) - two identical xml files");
out("should not get any event");
b1.merge(b2);
check(b1.toString().equals(b2.toString()), " - no diff");
check(b1.isEqualTo(b2), " - equals");
// One mixed up document, but should be the same
setTest("Merge(Update) - two identical xml files (one mixed up)");
this.readDocument("tm01_g2.xml");
out("creating the bean graph3");
b3 = Book.createGraph(doc);
l3 = new MyListener(b3);
b3.addPropertyChangeListener(l3);
b3.merge(b1);
check(b3.isEqualTo(b1), " - equals");
//
// Change only one element of the second graph
//
setTest("Merge(Update) - changing one property");
String s1 = "This is the new summary";
String s2 = b2.getSummary();
// g1/g2
this.mute(true);
b2.setSummary(s1);
out("should get one event for Summary");
this.mute(false);
b1.merge(b2);
b1.write(System.out);
check(b2.isEqualTo(b1), " - equals");
// g1/g3
this.mute(true);
b1.setSummary(s2);
this.mute(false);
out("should not get any event");
b1.merge(b3);
check(b3.isEqualTo(b1), " - equals");
this.mute(true);
b2.setSummary(s2);
//
// Mixing array of strings
//
setTest("Merge(Update) - mixing array of strings");
check(b1.getAuthor(0).equals(b2.getAuthor(0)), "initial match");
check(b1.getAuthor(1).equals(b2.getAuthor(1)), "initial match");
check(b1.getAuthor(2).equals(b2.getAuthor(2)), "initial match");
this.mute(false);
String [] ss1 = b2.getAuthor();
String [] ss2 = new String[3];
ss2[0] = ss1[2];
ss2[1] = ss1[1];
ss2[2] = ss1[0];
b2.setAuthor(ss2);
check(b1.getAuthor(0).equals(b2.getAuthor(2)), "mixed");
check(b1.getAuthor(1).equals(b2.getAuthor(1)), "mixed");
check(b1.getAuthor(2).equals(b2.getAuthor(0)), "mixed");
out("should not get any event");
b1.merge(b2);
check(b2.isEqualTo(b1), " - equals");
this.mute(true);
b2.setAuthor(ss1);
check(b1.getAuthor(0).equals(b2.getAuthor(0)), "reset match");
check(b1.getAuthor(1).equals(b2.getAuthor(1)), "reset match");
check(b1.getAuthor(2).equals(b2.getAuthor(2)), "reset match");
//
// Mixing array of beans
//
setTest("Merge(Update) - mixing array of beans");
check(b1.getChapter(0).isEqualTo(b2.getChapter(0)), "initial match");
check(b1.getChapter(1).isEqualTo(b2.getChapter(1)), "initial match");
check(b1.getChapter(2).isEqualTo(b2.getChapter(2)), "initial match");
this.mute(false);
Chapter [] cc1 = b2.getChapter();
Chapter [] cc2 = new Chapter[3];
cc2[0] = cc1[2];
cc2[1] = cc1[1];
cc2[2] = cc1[0];
b2.setChapter(cc2);
check(b1.getChapter(0).isEqualTo(b2.getChapter(2)), "mixed");
check(b1.getChapter(1).isEqualTo(b2.getChapter(1)), "mixed");
check(b1.getChapter(2).isEqualTo(b2.getChapter(0)), "mixed");
out("should not get any event");
b1.merge(b2);
check(b2.isEqualTo(b1), " - equals");
this.mute(true);
b2.setChapter(cc1);
check(b1.getChapter(0).isEqualTo(b2.getChapter(0)), "reset match");
check(b1.getChapter(1).isEqualTo(b2.getChapter(1)), "reset match");
check(b1.getChapter(2).isEqualTo(b2.getChapter(2)), "reset match");
//
// Removing a String elt from an array
//
setTest("Merge(Update) - remove elt from array of strings");
check(b1.getAuthor(0).equals(b2.getAuthor(0)), "initial match");
check(b1.getAuthor(1).equals(b2.getAuthor(1)), "initial match");
check(b1.getAuthor(2).equals(b2.getAuthor(2)), "initial match");
this.mute(false);
s1 = b2.getAuthor(1);
out("should get one remove event from deletion");
b2.removeAuthor(s1);
check(b1.getAuthor(0).equals(b2.getAuthor(0)), "match after rem");
check(b1.getAuthor(2).equals(b2.getAuthor(1)), "match after rem");
out("should get one remove event from merge");
b1.merge(b2);
check(b1.getAuthor(0).equals(b2.getAuthor(0)), "match");
check(b1.getAuthor(1).equals(b2.getAuthor(1)), "match");
check(b1.sizeAuthor() == b2.sizeAuthor(), "correct size");
check(b2.isEqualTo(b1), " - equals");
//
// Adding a String elt from an array
//
setTest("Merge(Update) - add elt from array of strings");
this.mute(false);
out("should get one event for elt added");
b2.addAuthor(s1);
check(b2.getAuthor(2).equals(s1), "added");
out("should get one event for elt added from merge");
//out("Here is b1:");
//b1.writeNoReindent(System.out);
//out("Here is b2:");
//b2.writeNoReindent(System.out);
b1.merge(b2);
//out("Here is b1:");
//b1.writeNoReindent(System.out);
check(b1.getAuthor(0).equals(b2.getAuthor(0)), "match");
check(b1.getAuthor(1).equals(b2.getAuthor(1)), "match");
check(b1.getAuthor(2).equals(b2.getAuthor(2)), "match");
check(b1.sizeAuthor() == b2.sizeAuthor(), "correct size");
check(b2.isEqualTo(b1), " - equals");
//
// Removing a Bean elt from an array
//
setTest("Merge(Update) - remove elt from array of beans");
check(b1.getChapter(0).isEqualTo(b2.getChapter(0)), "initial match");
check(b1.getChapter(1).isEqualTo(b2.getChapter(1)), "initial match");
check(b1.getChapter(2).isEqualTo(b2.getChapter(2)), "initial match");
this.mute(false);
Chapter c1 = b2.getChapter(1);
Chapter c2 = (Chapter)c1.clone();
out("should get one remove event from deletion");
b2.removeChapter(c1);
check(b1.getChapter(0).isEqualTo(b2.getChapter(0)), "match after rem");
check(b1.getChapter(2).isEqualTo(b2.getChapter(1)), "match after rem");
out("should get one remove event from merge");
b1.merge(b2);
check(b1.getChapter(0).isEqualTo(b2.getChapter(0)), "match");
check(b1.getChapter(1).isEqualTo(b2.getChapter(1)), "match");
check(b1.sizeChapter() == b2.sizeChapter(), "correct size");
check(b2.isEqualTo(b1), " - equals");
//
// Adding a Bean elt from an array
//
setTest("Merge(Update) - add elt from array of strings");
this.mute(false);
out("should get one event for elt added");
b2.addChapter(c2);
check(b2.getChapter(2).isEqualTo(c2), "added");
out("should get one event for elt added from merge");
b1.merge(b2);
check(b1.getChapter(0).isEqualTo(b2.getChapter(0)), "match");
check(b1.getChapter(1).isEqualTo(b2.getChapter(1)), "match");
check(b1.getChapter(2).isEqualTo(b2.getChapter(2)), "match");
check(b1.sizeChapter() == b2.sizeChapter(), "correct size");
check(b2.isEqualTo(b1), " - equals");
//
// Compare two graphs with missing nodes and elements
//
Book b4, b5, b6;
this.readDocument("tm01_g1.xml");
out("creating the bean graph1");
b4 = Book.createGraph(doc);
b5 = (Book)b4.clone();
b6 = (Book)b4.clone();
setTest("comparing graphs with 1 null elts");
check(b4.sizeChapter() == 3);
check(b5.sizeChapter() == 3);
// bean[] full / bean null
check(b4.isEqualTo(b5));
setTest("comparing graphs with null indexed elts");
// g1.bean[] has 1 null / g2.bean[] has 1 null / bean null
b4.setChapter(1, null);
b5.setChapter(2, null);
check(!b4.isEqualTo(b5));
b4.merge(b5);
check(b4.sizeChapter() == 3, "correct new array sise");
check(b4.getChapter(0).isEqualTo(b5.getChapter(0)), "elt ok");
check(b4.getChapter(1) == null, "elt ok");
check(b4.getChapter(2).isEqualTo(b5.getChapter(1)), "elt ok");
setTest("comparing graphs with null single bean elt");
// g1.bean non null / g2.bean is null
b4 = (Book)b6.clone();
b5 = (Book)b6.clone();
Content ct = new Content();
ct.setTitle("This is a title");
ct.setComment("And this is a comment");
check(b4.isEqualTo(b5));
b5.setContent(ct);
check(!b4.isEqualTo(b5));
b4.merge(b5);
check(b4.getContent().isEqualTo(b5.getContent()));
// Clone an element which is not part of a graph
Chapter c3 = new Chapter();
c3.setComment("This is a comment");
c3.setNumber("123");
c3.addParagraph("This is a new paragraph");
Chapter c4 = (Chapter)c3.clone();
// Add both elements to two identical graphs - should get two
// identical graphs
setTest("cloning a new bean");
Book b7 = (Book)b2.clone();
Book b8 = (Book)b2.clone();
b7.addChapter(c3);
b8.addChapter(c4);
check(c3.isEqualTo(c4), "objects equal");
check(b7.isEqualTo(b8), "same graph once added");
//
// Test the attributes. When we merge graphs, we need to make
// sure that the attributes are also merged.
//
this.readDocument("tm01_g2.xml");
out("creating the bean graph1");
b1 = Book.createGraph(doc);
// g3 and g2 elements are identicals, g3 has attributes,
// g2 has not.
this.readDocument("tm01_g3.xml");
out("creating the bean graph2");
b2 = Book.createGraph(doc);
// Make sure that we can clone a part of the graph without loosing
// the attributes.
BaseBean bb = b2.getChapter(0);
// Should see the chapter attribute
out(bb.dumpDomNode());
b3 = (Book)b1.clone();
int index = b3.addValue("Chapter", bb.clone());
bb = b3.getChapter(index);
// Should see the chapter attribute on this cloned element
out(bb.dumpDomNode());
l1 = new MyListener(b1);
l1.mute(true);
b1.addPropertyChangeListener(l1);
// b2 should never change, so we should never receive anything
// on this listener
l2 = new MyListener(b2);
b2.addPropertyChangeListener(l2);
// The only events we should have when we merge are the
// attributes events, because the graphs only differ by attr.
setTest("Merging attributes");
check(!b1.isEqualTo(b2), "shouldn't be equals (diff an attr)");
//GraphManager.debug(true);
b1.merge(b2);
check(b1.isEqualTo(b2), "should be equals");
// Make sure that b1 has the attributes
s1 = b1.getAttributeValue("good");
check(s1 != null, "attr on root != null");
if (s1 != null) {
check(s1.equals("no"), "attr on root");
}
s1 = b1.getAttributeValue("summary", "length");
check(s1 != null, "attr on summary != null");
if (s1 != null) {
check(s1.equals("123"), "attr on summary");
}
s1 = b1.getAttributeValue("summary", "lang");
check(s1 != null, "attr on summary != null");
if (s1 != null) {
check(s1.equals("us"), "attr on summary");
}
s1 = b1.getAttributeValue("chapter", 1, "title");
out(s1);
check(s1 != null, "attr on chapter != null");
if (s1 != null) {
check(s1.equals("First"), "attr on chapter");
}
s1 = b1.getAttributeValue("chapter", 2, "title");
out(s1);
check(s1 != null, "attr on chapter != null");
if (s1 != null) {
check(s1.equals("Second"), "attr on chapter");
}
//
// Make sure that we do not consume too much memory
//
// // Ignore the first one
// this.getKMemUsage();
//
// int k1 = this.getKMemUsage();
//
// Book newBook;
//
// this.readDocument("tm01_g3.xml");
// out("creating the bean graph for memory test");
// newBook = Book.createGraph(doc);
//
// int maxLoop = 50;
// BaseBean[] aBook = new BaseBean[maxLoop];
// for(int loop=0; loop<maxLoop; loop++) {
// aBook[loop] = (BaseBean)newBook.clone();
// }
//
// int k2 = this.getKMemUsage() - k1;
//
// float diff = (float)(k2 - memUsageReference);
//
// if (diff > 0) {
// // We consume more memory than excepted
// float p = diff/memUsageReference*100;
// if (p > 20.0) {
// out("It seems that the last schema2beans code changes have increased the memory consumption by " + p + "%");
// out("If this is expected and acceptable, change the memUsageReference value in TestMerge.java, to be " + k2);
// }
// } else {
///* // We consume less memory than expected
// float p = Math.abs(diff)/memUsageReference*100;
// if (p > 25.0) {
// out("It seems that the last schema2beans code changes have decreased the memory consumption by " + p + "% !!!");
// out("Please, change the memUsageReference value in TestMerge.java, to be " + k2);
// } */
// }
// out("memory test done");
readDocument("tm01_g1.xml");
b1 = Book.createGraph(doc);
readDocument("tm01_g4.xml");
out("creating the bean graph for the comment merge test");
Book commentedGraph = Book.createGraph(doc);
b1.merge(commentedGraph);
out(b1);
}
}