Skip to content

Commit

Permalink
Merge pull request #184 from xzhong66/migrateCGLIB
Browse files Browse the repository at this point in the history
Migrate CGLIB to ByteBuddy
  • Loading branch information
nimisha84 authored Jun 23, 2022
2 parents f26fd0a + 048f7f2 commit ff9ab96
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 159 deletions.
14 changes: 7 additions & 7 deletions ipp-v3-java-devkit/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,7 @@
<artifactId>jaxb2-commons-lang</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.12</version>
</dependency>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-commons</artifactId>
Expand Down Expand Up @@ -119,7 +114,12 @@
<artifactId>jmockit</artifactId>
<version>1.25</version>
<scope>test</scope>
</dependency>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.12.10</version>
</dependency>
</dependencies>
<build>
<testResources>
Expand Down
150 changes: 44 additions & 106 deletions ipp-v3-java-devkit/src/main/java/com/intuit/ipp/query/GenerateQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
*******************************************************************************/
package com.intuit.ipp.query;

import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;

import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;

import com.intuit.ipp.core.IEntity;
import com.intuit.ipp.query.expr.BooleanPath;
Expand All @@ -30,87 +30,87 @@
import com.intuit.ipp.query.expr.NumberPath;
import com.intuit.ipp.query.expr.StringPath;
import com.intuit.ipp.util.Logger;
import net.sf.cglib.proxy.NoOp;

/**
* Class used to generate the query string
*
*
*/
public final class GenerateQuery {

/**
* logger instance
*/
private static final org.slf4j.Logger LOG = Logger.getLogger();

/**
* variable LEN_3
*/
private static final int LEN_3 = 3;

/**
* variable path
*/
public static ThreadLocal<Path<?>> path = new ThreadLocal<Path<?>>();

/**
* varriable message
*/
private static QueryMessage message = new QueryMessage();

/**
* variable CLASSNAME_SPLIT_PATTERN
*/
private static final String CLASSNAME_SPLIT_PATTERN = "\\$";

/**
* Constructor to have private modifier as it has only static methods
*/
private GenerateQuery() {
}

/**
* Method to create the query entity for the given class
*
*
* @param cl the class
* @return the proxified object
*/
@SuppressWarnings("unchecked")
public static <T> T createQueryEntity(Class<T> cl) {
Enhancer enhancer = new Enhancer();
Class<?> proxied = null;
if (cl.isInterface()) {
LOG.debug("The given class is interface");
//enhancer.setInterfaces(new Class[] { cl });
//enhancer.setCallback(new MyMethodInterceptor());
} else {
enhancer.setSuperclass(cl);
proxied = new ByteBuddy()
.subclass(cl)
.method(ElementMatchers.not(ElementMatchers.isClone().or(ElementMatchers.isFinalizer()).or(ElementMatchers.isEquals()).or(ElementMatchers.isHashCode()).or(ElementMatchers.isToString())))
.intercept(MethodDelegation.to(new MyMethodInterceptor()))
.make()
.load(GenerateQuery.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
}
try {
return (T) proxied.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
LOG.error(e.getMessage());
throw new RuntimeException(e);
}
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbacks(new Callback[] {NoOp.INSTANCE, new MyMethodInterceptor()});
return (T) enhancer.create();
}

/**
* Method to create the query for the given entity
*
*
* @param entity the entity
* @return the proxified object
*/
@SuppressWarnings("unchecked")
public static <T> T createQueryEntity(T entity) {
Class<?> cl = entity.getClass();
Enhancer enhancer = new Enhancer();
if (cl.isInterface()) {
LOG.debug("The given entity is interface");
//enhancer.setInterfaces(new Class[] { cl });
//enhancer.setCallback(new MyMethodInterceptor());
} else {
enhancer.setSuperclass(cl);
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbacks(new Callback[] {NoOp.INSTANCE, new MyMethodInterceptor()});
}
return (T) enhancer.create();
return (T) createQueryEntity(cl);
}


/**
* when no handler for specific return type is defined which means properties of that type cannot be inserted in filter expression but can be
* listed in select part, it will return Path
*
*
* @param ret the object
* @return path the path
*/
Expand All @@ -121,15 +121,15 @@ public static <T> T createQueryEntity(T entity) {
return new Path<Object>(currentPath.getPathString().concat(".*"), currentPath.getEntity());
} else {
String name = ret.getClass().getSimpleName();
String[] extracted = name.split("\\$\\$");
String[] extracted = name.split(CLASSNAME_SPLIT_PATTERN);
return new Path<Object>("*", extracted[0]);
}
}

/**
* When return type is Calendar, it will create CalendarPath which will expose filter methods accepting java.util.Calendar, java.util.Date and
* java.sql.Date
*
*
* @param ret
* @return
*/
Expand All @@ -141,7 +141,7 @@ public static <T> T createQueryEntity(T entity) {

/**
* Method to get the calendar path
*
*
* @param ret the date
* @return CalendarPath the calendar path
*/
Expand All @@ -153,7 +153,7 @@ public static <T> T createQueryEntity(T entity) {

/**
* When return type is String, it will create StringPath which will expose filter methods accepting only String
*
*
* @param ret the string
* @return StringPath the string path
*/
Expand All @@ -165,7 +165,7 @@ public static <T> T createQueryEntity(T entity) {

/**
* Method to get the number path
*
*
* @param ret the number
* @return NumberPath the number path
*/
Expand All @@ -177,7 +177,7 @@ public static <T> T createQueryEntity(T entity) {

/**
* Method to get the boolean path
*
*
* @param ret the boolean
* @return BooleanPath the boolean path
*/
Expand All @@ -189,7 +189,7 @@ public static <T> T createQueryEntity(T entity) {

/**
* Method to get the Enum path
*
*
* @param ret the enum
* @return EnumPath the enum path
*/
Expand All @@ -201,7 +201,7 @@ public static <T> T createQueryEntity(T entity) {

/**
* Method to get the optional syntax
*
*
* @param path the path
* @param pathlist the path list
* @return OptionalSyntax the optional syntax
Expand All @@ -222,15 +222,15 @@ public static <T extends IEntity> OptionalSyntax select(Path<?> path, Path<?>...

/**
* Method to get the optional syntax for the given entity
*
*
* @param entity the entity
* @return OptionalSyntax the optional syntax
*/
public static <T extends IEntity> OptionalSyntax selectCount(T entity) {
resetQueryMessage();
getMessage().setSQL("SELECT");
String name = entity.getClass().getSimpleName();
String extracted[] = name.split("\\$\\$");
String extracted[] = name.split(CLASSNAME_SPLIT_PATTERN);
getMessage().setCount(true);
if (extracted.length == LEN_3) {
getMessage().setEntity(extracted[0]);
Expand All @@ -240,7 +240,7 @@ public static <T extends IEntity> OptionalSyntax selectCount(T entity) {

/**
* Method to get the query message
*
*
* @return QueryMessage the query message
*/
public static QueryMessage getMessage() {
Expand All @@ -249,7 +249,7 @@ public static QueryMessage getMessage() {

/**
* Method to set the query message
*
*
* @param mess the query message
*/
public static void setMessage(QueryMessage mess) {
Expand All @@ -262,66 +262,4 @@ public static void setMessage(QueryMessage mess) {
public static void resetQueryMessage() {
setMessage(new QueryMessage());
}

/**
* Callback filter which will filter out callback triggers for several {@link Object} methods.
*/
private static final CallbackFilter CALLBACK_FILTER = new CallbackFilter() {

@Override
public int accept(Method method) {
if (isFinalizeMethod(method) || isCloneMethod(method) || isEqualsMethod(method)
|| isHashCodeMethod(method) || isToStringMethod(method)) {
return 0;
}
return 1;
}

/**
* Determine whether the given method is a "finalize" method.
* @see java.lang.Object#finalize()
*/
private boolean isFinalizeMethod(Method method) {
return (method != null && method.getName().equals("finalize") &&
method.getParameterTypes().length == 0);
}

/**
* Determine whether the given method is a "finalize" method.
* @see java.lang.Object#finalize()
*/
private boolean isCloneMethod(Method method) {
return (method != null && method.getName().equals("clone") &&
method.getParameterTypes().length == 0);
}

/**
* Determine whether the given method is an "equals" method.
* @see java.lang.Object#equals(Object)
*/
private boolean isEqualsMethod(Method method) {
if (method == null || !method.getName().equals("equals")) {
return false;
}
Class<?>[] paramTypes = method.getParameterTypes();
return (paramTypes.length == 1 && paramTypes[0] == Object.class);
}

/**
* Determine whether the given method is a "hashCode" method.
* @see java.lang.Object#hashCode()
*/
private boolean isHashCodeMethod(Method method) {
return (method != null && method.getName().equals("hashCode") && method.getParameterTypes().length == 0);
}

/**
* Determine whether the given method is a "toString" method.
* @see java.lang.Object#toString()
*/
private boolean isToStringMethod(Method method) {
return (method != null && method.getName().equals("toString") && method.getParameterTypes().length == 0);
}
};

}
Loading

0 comments on commit ff9ab96

Please sign in to comment.