Added a test/demo showing how to use the cloner with various examples

of the kinds of classes it can work with.
cleanup_build_scripts
Paul Speed 9 years ago
parent 70154f1b1d
commit 90af571f76
  1. 368
      jme3-examples/src/main/java/jme3test/app/TestCloner.java

@ -0,0 +1,368 @@
/*
* Copyright (c) 2016 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * 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.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR
* 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.
*/
package jme3test.app;
import java.util.*;
import com.jme3.util.clone.*;
/**
*
*
* @author Paul Speed
*/
public class TestCloner {
public static void main( String... args ) {
System.out.println("Clone test:");
Cloner cloner = new Cloner();
RegularObject ro = new RegularObject(42);
System.out.println("Regular Object:" + ro);
RegularObject roCloneLegacy = ro.clone();
System.out.println("Regular Object Clone:" + roCloneLegacy);
RegularObject roClone = cloner.clone(ro);
System.out.println("cloner: Regular Object Clone:" + roClone);
System.out.println("------------------------------------");
System.out.println();
cloner = new Cloner();
RegularSubclass rsc = new RegularSubclass(69, "test");
System.out.println("Regular subclass:" + rsc);
RegularSubclass rscCloneLegacy = (RegularSubclass)rsc.clone();
System.out.println("Regular subclass Clone:" + rscCloneLegacy);
RegularSubclass rscClone = cloner.clone(rsc);
System.out.println("cloner: Regular subclass Clone:" + rscClone);
System.out.println("------------------------------------");
System.out.println();
cloner = new Cloner();
Parent parent = new Parent("Foo", 34);
System.out.println("Parent:" + parent);
Parent parentCloneLegacy = parent.clone();
System.out.println("Parent Clone:" + parentCloneLegacy);
Parent parentClone = cloner.clone(parent);
System.out.println("cloner: Parent Clone:" + parentClone);
System.out.println("------------------------------------");
System.out.println();
cloner = new Cloner();
GraphNode root = new GraphNode("root");
GraphNode child1 = root.addLink("child1");
GraphNode child2 = root.addLink("child2");
GraphNode shared = child1.addLink("shared");
child2.addLink(shared);
// Add a circular reference to get fancy
shared.addLink(root);
System.out.println("Simple graph:");
root.dump(" ");
GraphNode rootClone = cloner.clone(root);
System.out.println("clone:");
rootClone.dump(" ");
System.out.println("original:");
root.dump(" ");
GraphNode reclone = Cloner.deepClone(root);
System.out.println("reclone:");
reclone.dump(" ");
System.out.println("------------------------------------");
System.out.println();
cloner = new Cloner();
ArrayHolder arrays = new ArrayHolder(5, 3, 7, 3, 7, 2, 1, 4);
System.out.println("Array holder:" + arrays);
ArrayHolder arraysClone = cloner.clone(arrays);
System.out.println("Array holder clone:" + arraysClone);
}
public static class RegularObject implements Cloneable {
protected int i;
public RegularObject( int i ) {
this.i = i;
}
public RegularObject clone() {
try {
return (RegularObject)super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException(e);
}
}
public String toString() {
return getClass().getSimpleName() + "@" + System.identityHashCode(this)
+ "[i=" + i + "]";
}
}
public static class RegularSubclass extends RegularObject {
protected String name;
public RegularSubclass( int i, String name ) {
super(i);
this.name = name;
}
public String toString() {
return getClass().getSimpleName() + "@" + System.identityHashCode(this)
+ "[i=" + i + ", name=" + name + "]";
}
}
public static class Parent implements Cloneable, JmeCloneable {
private RegularObject ro;
private RegularSubclass rsc;
public Parent( String name, int age ) {
this.ro = new RegularObject(age);
this.rsc = new RegularSubclass(age, name);
}
public Parent clone() {
try {
return (Parent)super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException(e);
}
}
public void cloneFields( Cloner cloner, Object original ) {
this.ro = cloner.clone(ro);
this.rsc = cloner.clone(rsc);
}
public String toString() {
return getClass().getSimpleName() + "@" + System.identityHashCode(this)
+ "[ro=" + ro + ", rsc=" + rsc + "]";
}
}
public static class GraphNode implements Cloneable, JmeCloneable {
private String name;
private List<GraphNode> links = new ArrayList<>();
public GraphNode( String name ) {
this.name = name;
}
public void dump( String indent ) {
dump(indent, new HashSet<GraphNode>());
}
private void dump( String indent, Set<GraphNode> visited ) {
if( visited.contains(this) ) {
// already been here
System.out.println(indent + this + " ** circular.");
return;
}
System.out.println(indent + this);
visited.add(this);
for( GraphNode n : links ) {
n.dump(indent + " ", visited);
}
visited.remove(this);
}
public GraphNode addLink( String name ) {
GraphNode node = new GraphNode(name);
links.add(node);
return node;
}
public GraphNode addLink( GraphNode node ) {
links.add(node);
return node;
}
public List<GraphNode> getLinks() {
return links;
}
public GraphNode clone() {
try {
return (GraphNode)super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException(e);
}
}
public void cloneFields( Cloner cloner, Object original ) {
this.links = cloner.clone(links);
/*
// manually clone the list for a sec
List<GraphNode> cloneList = (List<GraphNode>)((ArrayList<GraphNode>)links).clone(); //new ArrayList<GraphNode>();
for( int i = 0; i < links.size(); i++ ) {
cloneList.set(i, cloner.clone(links.get(i)));
}
links = cloneList;*/
}
public String toString() {
return getClass().getSimpleName() + "@" + System.identityHashCode(this)
+ "[name=" + name + "]";
}
}
public static class ArrayHolder implements JmeCloneable {
private int[] intArray;
private int[][] intArray2D;
private Object[] objects;
private RegularObject[] regularObjects;
private String[] strings;
public ArrayHolder( int... values ) {
this.intArray = values;
this.intArray2D = new int[values.length][2];
for( int i = 0; i < values.length; i++ ) {
intArray2D[i][0] = values[i] + 1;
intArray2D[i][1] = values[i] * 2;
}
this.objects = new Object[values.length];
this.regularObjects = new RegularObject[values.length];
this.strings = new String[values.length];
for( int i = 0; i < values.length; i++ ) {
objects[i] = values[i];
regularObjects[i] = new RegularObject(values[i]);
strings[i] = String.valueOf(values[i]);
}
}
public ArrayHolder clone() {
try {
return (ArrayHolder)super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException(e);
}
}
public void cloneFields( Cloner cloner, Object original ) {
intArray = cloner.clone(intArray);
intArray2D = cloner.clone(intArray2D);
// Boxed types are not cloneable so this will fail
//objects = cloner.clone(objects);
regularObjects = cloner.clone(regularObjects);
// Strings are also not cloneable
//strings = cloner.clone(strings);
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("intArray=" + intArray);
for( int i = 0; i < intArray.length; i++ ) {
if( i == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append(intArray[i]);
}
sb.append("], ");
sb.append("intArray2D=" + intArray2D);
for( int i = 0; i < intArray2D.length; i++ ) {
if( i == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append("intArray2D[" + i + "]=" + intArray2D[i]);
for( int j = 0; j < 2; j++ ) {
if( j == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append(intArray2D[i][j]);
}
sb.append("], ");
}
sb.append("], ");
sb.append("objectArray=" + objects);
for( int i = 0; i < objects.length; i++ ) {
if( i == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append(objects[i]);
}
sb.append("], ");
sb.append("objectArray=" + regularObjects);
for( int i = 0; i < regularObjects.length; i++ ) {
if( i == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append(regularObjects[i]);
}
sb.append("], ");
sb.append("stringArray=" + strings);
for( int i = 0; i < strings.length; i++ ) {
if( i == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append(strings[i]);
}
sb.append("]");
return getClass().getSimpleName() + "@" + System.identityHashCode(this)
+ "[" + sb + "]";
}
}
}
Loading…
Cancel
Save