Skip to content

Commit

Permalink
new dependency objenesis for instantiate object from class objects
Browse files Browse the repository at this point in the history
- new method to create new instances of a given class object with
objenesis
- tagged class SilentEqualsHashCodeAndToStringEvaluator as deprecated
  • Loading branch information
astrapi69 committed Mar 15, 2019
1 parent b89d66f commit 6b2d835
Show file tree
Hide file tree
Showing 10 changed files with 271 additions and 157 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@
Version 2.6-SNAPSHOT
-------------

ADDED:

- new methods for copy object with reflection
- new dependency objenesis for instantiate object from class objects
- new method to create new instances of a given class object

CHANGED:

- moved jobject-merge-api to its own project
- tagged class SilentEqualsHashCodeAndToStringEvaluator as deprecated

Version 2.5.1
-------------
Expand Down
21 changes: 0 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ Than you can add the dependency to your dependencies:
<jobject-diff.version>${jobject-extensions.version}</jobject-diff.version>
<jobject-evaluate.version>${jobject-extensions.version}</jobject-evaluate.version>
<jobject-merge.version>${jobject-extensions.version}</jobject-merge.version>
<jobject-merge-api.version>${jobject-extensions.version}</jobject-merge-api.version>
...
</properties>
Expand Down Expand Up @@ -165,20 +164,6 @@ Add the following maven dependency to your project `pom.xml` if you want to impo
...
</dependencies>
Add the following maven dependency to your project `pom.xml` if you want to import only the jobject-merge-api:

<dependencies>
...
<!-- JOBJECT-MERGE-API DEPENDENCY -->
<dependency>
<groupId>de.alpharogroup</groupId>
<artifactId>jobject-merge-api</artifactId>
<version>${jobject-merge-api.version}</version>
</dependency>
...
</dependencies>


You can of course import all dependencies of jobject-extensions:

<dependencies>
Expand Down Expand Up @@ -226,12 +211,6 @@ You can of course import all dependencies of jobject-extensions:
<artifactId>jobject-merge</artifactId>
<version>${jobject-merge.version}</version>
</dependency>
<!-- JOBJECT-MERGE-API DEPENDENCY -->
<dependency>
<groupId>de.alpharogroup</groupId>
<artifactId>jobject-merge-api</artifactId>
<version>${jobject-merge-api.version}</version>
</dependency>
...
</dependencies>

Expand Down
2 changes: 1 addition & 1 deletion jobject-copy/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<artifactId>jobject-copy</artifactId>

<dependencies>

<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
import java.lang.reflect.Modifier;
import java.util.Arrays;

import lombok.NonNull;
import org.apache.commons.beanutils.BeanUtils;

import de.alpharogroup.reflection.ReflectionExtensions;
import lombok.NonNull;
import lombok.experimental.UtilityClass;

/**
Expand All @@ -44,130 +44,190 @@
@UtilityClass
public final class CopyObjectExtensions
{

/**
* Copy the given original object
*
* @param original the original object
* @return a copy of the given original object
* @throws IllegalAccessException if the caller does not have access to the property accessor method
* @throws InstantiationException Thrown if one of the following reasons: the class object
* <ul>
* <li>represents an abstract class</li>
* <li>represents an interface</li>
* <li>represents an array class</li>
* <li>represents a primitive type</li>
* <li>represents {@code void}</li>
* <li>has no nullary constructor</li>
* </ul>
*/
public static<T> T copyObject(@NonNull T original) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
T destination = (T) original.getClass().newInstance();
return copyObject(original, destination);
}

/**
* Copy the given original object to the given destination object. This also works on private
* fields.
*
* @param <ORIGINAL> the generic type of the original object.
* @param <DESTINATION> the generic type of the destination object.
* @param original the original object.
* @param destination the destination object.
* @return a copy of the given original object
* @throws IllegalAccessException if the caller does not have access to the property accessor method
* @throws InstantiationException Thrown if one of the following reasons: the class object
* <ul>
* <li>represents an abstract class</li>
* <li>represents an interface</li>
* <li>represents an array class</li>
* <li>represents a primitive type</li>
* <li>represents {@code void}</li>
* <li>has no nullary constructor</li>
* </ul>
*/
public static <ORIGINAL, DESTINATION> DESTINATION copyObject(@NonNull ORIGINAL original, @NonNull DESTINATION destination) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
for (Field field : original.getClass().getDeclaredFields()) {
if (copyField(field, original, destination)) continue;
}
return destination;
}

/**
* Copy the given original object.
*
* @param <T>
* the generic type of the given object
* @param original
* the original object
* @return a copy of the given original object
* @throws IllegalAccessException
* if the caller does not have access to the property accessor method
* @throws InstantiationException
* Thrown if one of the following reasons: the class object
* <ul>
* <li>represents an abstract class</li>
* <li>represents an interface</li>
* <li>represents an array class</li>
* <li>represents a primitive type</li>
* <li>represents {@code void}</li>
* <li>has no nullary constructor</li>
* </ul>
* @throws ClassNotFoundException
* is thrown if the class cannot be located
*/
public static <T> T copyObject(@NonNull T original)
throws IllegalAccessException, InstantiationException, ClassNotFoundException
{
T destination = ReflectionExtensions.newInstance(original);
return copyObject(original, destination);
}

/**
* Copy the given original object to the given destination object. This also works on private
* fields.
*
* @param <ORIGINAL>
* the generic type of the original object.
* @param <DESTINATION>
* the generic type of the destination object.
* @param original
* the original object.
* @param destination
* the destination object.
* @return a copy of the given original object
* @throws IllegalAccessException
* if the caller does not have access to the property accessor method
* @throws InstantiationException
* Thrown if one of the following reasons: the class object
* <ul>
* <li>represents an abstract class</li>
* <li>represents an interface</li>
* <li>represents an array class</li>
* <li>represents a primitive type</li>
* <li>represents {@code void}</li>
* <li>has no nullary constructor</li>
* </ul>
* @throws ClassNotFoundException
* is thrown if the class cannot be located
*/
public static <ORIGINAL, DESTINATION> DESTINATION copyObject(@NonNull ORIGINAL original,
@NonNull DESTINATION destination)
throws IllegalAccessException, InstantiationException, ClassNotFoundException
{
for (Field field : original.getClass().getDeclaredFields())
{
if (copyField(field, original, destination))
{
continue;
}
}
return destination;
}

/**
* Copy the given original object to the given destination object. This also works on private
* fields.
*
* @param <ORIGINAL> the generic type of the original object.
* @param <DESTINATION> the generic type of the destination object.
* @param original the original object.
* @param destination the destination object.
* @param ignoreFields optional field names to ignore
* @param <ORIGINAL>
* the generic type of the original object.
* @param <DESTINATION>
* the generic type of the destination object.
* @param original
* the original object.
* @param destination
* the destination object.
* @param ignoreFields
* optional field names to ignore
* @return a copy of the given original object
* @throws IllegalAccessException if the caller does not have access to the property accessor method
* @throws InstantiationException Thrown if one of the following reasons: the class object
* <ul>
* <li>represents an abstract class</li>
* <li>represents an interface</li>
* <li>represents an array class</li>
* <li>represents a primitive type</li>
* <li>represents {@code void}</li>
* <li>has no nullary constructor</li>
* </ul>
* @throws IllegalAccessException
* if the caller does not have access to the property accessor method
* @throws InstantiationException
* Thrown if one of the following reasons: the class object
* <ul>
* <li>represents an abstract class</li>
* <li>represents an interface</li>
* <li>represents an array class</li>
* <li>represents a primitive type</li>
* <li>represents {@code void}</li>
* <li>has no nullary constructor</li>
* </ul>
* @throws ClassNotFoundException
* is thrown if the class cannot be located
*/
public static <ORIGINAL, DESTINATION> DESTINATION copyObject(@NonNull ORIGINAL original, @NonNull DESTINATION destination, String... ignoreFields) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
for (Field field : original.getClass().getDeclaredFields()) {
if ( Arrays.asList(ignoreFields).contains(field.getName()) || copyField(field, original, destination)) continue;
public static <ORIGINAL, DESTINATION> DESTINATION copyObject(@NonNull ORIGINAL original,
@NonNull DESTINATION destination, String... ignoreFields)
throws IllegalAccessException, InstantiationException, ClassNotFoundException
{
for (Field field : original.getClass().getDeclaredFields())
{
if (Arrays.asList(ignoreFields).contains(field.getName())
|| copyField(field, original, destination))
continue;
}
return destination;
}

/**
* Copy the given original object to the given destination object. This also works on private
* fields.
*
* @param <ORIGINAL> the generic type of the original object.
* @param <DESTINATION> the generic type of the destination object.
* @param field the field
* @param original the original object.
* @param destination the destination object.
* @return true if the field is null or final otherwise false
* @throws IllegalAccessException if the caller does not have access to the property accessor method
* @throws InstantiationException
* Thrown if one of the following reasons: the class object
* <ul>
* <li>represents an abstract class</li>
* <li>represents an interface</li>
* <li>represents an array class</li>
* <li>represents a primitive type</li>
* <li>represents {@code void}</li>
* <li>has no nullary constructor</li>
* </ul>
*/
public static <ORIGINAL, DESTINATION> boolean copyField(@NonNull Field field, @NonNull ORIGINAL original, @NonNull DESTINATION destination) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
field.setAccessible(true);
Object value = field.get(original);
if (value == null || Modifier.isFinal(field.getModifiers())) {
return true;
}
if (field.getType().isEnum()) {
Enum enumValue = (Enum) value;

/**
* Copy the given original object to the given destination object. This also works on private
* fields.
*
* @param <ORIGINAL>
* the generic type of the original object.
* @param <DESTINATION>
* the generic type of the destination object.
* @param field
* the field
* @param original
* the original object.
* @param destination
* the destination object.
* @return true if the field is null or final otherwise false
* @throws IllegalAccessException
* if the caller does not have access to the property accessor method
* @throws InstantiationException
* Thrown if one of the following reasons: the class object
* <ul>
* <li>represents an abstract class</li>
* <li>represents an interface</li>
* <li>represents an array class</li>
* <li>represents a primitive type</li>
* <li>represents {@code void}</li>
* <li>has no nullary constructor</li>
* </ul>
* @throws ClassNotFoundException
* is thrown if the class cannot be located
*/
@SuppressWarnings("unchecked")
public static <ORIGINAL, DESTINATION> boolean copyField(@NonNull Field field,
@NonNull ORIGINAL original, @NonNull DESTINATION destination)
throws IllegalAccessException, InstantiationException, ClassNotFoundException
{
field.setAccessible(true);
Object value = field.get(original);
if (value == null || Modifier.isFinal(field.getModifiers()))
{
return true;
}
if (field.getType().isEnum())
{
Enum<?> enumValue = (Enum<?>)value;
String name = enumValue.name();
field.set(destination, Enum.valueOf(field.getType().asSubclass(Enum.class), name));
} else if (field.getType().isPrimitive() || field.getType().equals(String.class)
|| field.getType().getSuperclass().equals(Number.class)
|| field.getType().equals(Boolean.class)) {
field.set(destination, value);
} else {
Object childObj = value;
if (childObj == original) {
field.set(destination, destination);
} else {
field.set(destination, copyObject(value));
}
}
return false;
}

}
else if (field.getType().isPrimitive() || field.getType().equals(String.class)
|| field.getType().getSuperclass().equals(Number.class)
|| field.getType().equals(Boolean.class))
{
field.set(destination, value);
}
else
{
Object childObj = value;
if (childObj == original)
{
field.set(destination, destination);
}
else
{
field.set(destination, copyObject(value));
}
}
return false;
}

/**
* Copy the given original object to the given destination object. This also works on private
* fields.
Expand Down
Loading

0 comments on commit 6b2d835

Please sign in to comment.