BeanToPropertyValueTransformer and commons-collections4 - java

In commons-collections 3.2.1 the following one-liner worked nicely to retrieve the myProperty values of the objects inside myCollection:
Collection<MyType> myTypes = (Collection<MyType>) CollectionUtils.collect(myCollection, new BeanToPropertyValueTransformer("myProperty"))
Only drawback is that generics are not supported, so type casting needs to be done.
What would be a solution that works in commons-collection4, taking advantage of generics?

Apparently they removed BeanToPropertyValueTransformer from the release of apache-commons-collection4.
I managed to achieve the same behavior by defininig a custom Transformer. The introduction of generics eliminates the necessity of casting the output collection:
Collection<MyInputType> myCollection = ...
Collection<MyType> myTypes = CollectionUtils.collect(myCollection, new Transformer<MyInputType, MyType>() {
#Override
public MyType transform(MyInputType input) {
return input.getMyProperty();
}
}
You could also write your own Transformer that uses reflection
class ReflectionTransformer<O>
implements
Transformer<Object, O> {
private String reflectionString;
public ReflectionTransformer(String reflectionString) {
this.reflectionString = reflectionString;
}
#SuppressWarnings("unchecked")
#Override
public O transform(
Object input) {
try {
return (O) BeanUtils.getProperty(input, reflectionString);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
and use it same as you used to do with BeanToPropertyValueTransformer
Collection<MyType> myTypes = CollectionUtils.collect(myCollection, new ReflectionTransformer<MyType>("myProperty"));

Try using the below class (using commons-collection4) instead -
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.lang.reflect.InvocationTargetException;
public class BeanToPropertyValueTransformer implements Transformer {
private final Log log = LogFactory.getLog(this.getClass());
private String propertyName;
private boolean ignoreNull;
public BeanToPropertyValueTransformer(final String propertyName) {
this(propertyName, false);
}
public BeanToPropertyValueTransformer(final String propertyName, final boolean ignoreNull) {
super();
if ((propertyName != null) && (propertyName.length() > 0)) {
this.propertyName = propertyName;
this.ignoreNull = ignoreNull;
} else {
throw new IllegalArgumentException(
"propertyName cannot be null or empty");
}
}
public Object transform(final Object object) {
Object propertyValue = null;
try {
propertyValue = PropertyUtils.getProperty(object, propertyName);
} catch (final IllegalArgumentException e) {
final String errorMsg = "Problem during transformation. Null value encountered in property path...";
if (ignoreNull) {
log.warn("WARNING: " + errorMsg + e);
} else {
final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
if (!BeanUtils.initCause(iae, e)) {
log.error(errorMsg, e);
}
throw iae;
}
} catch (final IllegalAccessException e) {
final String errorMsg = "Unable to access the property provided.";
final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
if (!BeanUtils.initCause(iae, e)) {
log.error(errorMsg, e);
}
throw iae;
} catch (final InvocationTargetException e) {
final String errorMsg = "Exception occurred in property's getter";
final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
if (!BeanUtils.initCause(iae, e)) {
log.error(errorMsg, e);
}
throw iae;
} catch (final NoSuchMethodException e) {
final String errorMsg = "No property found for name [" +
propertyName + "]";
final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
if (!BeanUtils.initCause(iae, e)) {
log.error(errorMsg, e);
}
throw iae;
}
return propertyValue;
}
public String getPropertyName() {
return propertyName;
}
public boolean isIgnoreNull() {
return ignoreNull;
}
}

Related

Count traffic separately for each SIM on 2SIM MTK-based phone

Any app I could find on GPlay counts traffic for both SIM while in Settings-Data Usage traffic is counted for each SIM. I used jd-gui to see how it's done and have found that classes from private API were used.
import android.net.INetworkStatsService;
import android.net.INetworkStatsService.Stub;
import android.net.INetworkStatsSession;
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
import android.net.NetworkStats;
import android.net.NetworkStats.Entry;
import android.net.NetworkStatsHistory;
import android.net.NetworkStatsHistory.Entry;
import android.net.NetworkTemplate;
Can I use reflection to use them?
Update.
I've tried to use Reflection. Executing this code give me an exception "java.lang.InstantiationException: can't instantiate class android.net.INetworkStatsService"
Class<Object> MyINetworkStatsService = null;
try {
MyINetworkStatsService = (Class<Object>) Class.forName("android.net.INetworkStatsService");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Object mStatsService = null;
try {
mStatsService = MyINetworkStatsService != null ? MyINetworkStatsService.newInstance() : null;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Upd. Because both StatsService and StatsSession are interfaces, I can't instantiate them and should use Proxy. Can anyone help with that?
Upd. I've made an effort
String id = getActiveSubscriberId(mContext);
try {
Object tmpl = null;
long stats = 0;
Class<?> a = Class.forName("android.net.NetworkTemplate");
Class<?> b = Class.forName("android.net.INetworkStatsService");
Method getState = b.getMethod("getNetworkTotalBytes", a, long.class, long.class);
Method[] am = a.getDeclaredMethods();
Method getTemplate = null;
for (Method m : am) {
if (m.getName().equalsIgnoreCase("buildTemplateMobileAll")) {
getTemplate = m;
break;
}
}
if (getTemplate != null) {
getTemplate.setAccessible(true);
tmpl = getTemplate.invoke(a.getClass(), id);
}
Object object = Proxy.newProxyInstance(b.getClass().getClassLoader(), b.getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("getNetworkTotalBytes")) {
return method.invoke(args[0], args[1], args[2], args[3]);
}
throw new RuntimeException("no method found");
}
});
Object[] args = {b.getClass(), tmpl, Long.MIN_VALUE, Long.MAX_VALUE};
stats = (long) ((b.getClass()) object).getState(args);
} catch (ClassNotFoundException e0) {
} catch (NoSuchMethodException e0) {
} catch (IllegalAccessException e0) {
} catch (InvocationTargetException e0) {
}
But it says that there is an error "Method call expected" in
stats = (long) ((b.getClass()) object).getState(args);
If I change this string like this
stats = (long) ((b) object).getState(args);
I get another error - "Unknown class: 'b'"

how to use generic jsonFile handler using guice?

I have 2 repositories classes:
public class ResponseRepository implements IRoutingResponseRepository {
private final String baselineFileName;
#Inject
#Singleton
public ResponseRepository(#Named("baseline_file") String baselineFileName) {
this.baselineFileName = baselineFileName;
}
#Override
public E2EResult getBaseLine() {
E2EResult e2EResult = null;
ObjectMapper mapper = new ObjectMapper();
try
{
e2EResult = mapper.readValue(new File(baselineFileName), E2EResult.class);
} catch (JsonGenerationException e)
{
e.printStackTrace();
} catch (JsonMappingException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return e2EResult;
}
}
and
public class StatsRepository implements IRoutingResponseRepository {
private final String baselineFileName;
#Inject
#Singleton
public StatsRepository(#Named("stats_file") String baselineFileName) {
this.baselineFileName = baselineFileName;
}
#Override
public StatsObj getStats() {
StatsObj statsObj = null;
ObjectMapper mapper = new ObjectMapper();
try
{
statsObj = mapper.readValue(new File(baselineFileName), StatsObj.class);
} catch (JsonGenerationException e)
{
e.printStackTrace();
} catch (JsonMappingException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return statsObj;
}
}
how can I refactor the common code to be generic one?
and also I want guice to use fileName = E2EResult.csv when <E2EResult> and fileName = StatsObj.csv when <StatsObj>
I have tried:
but I wrote the generics incorrectly. It shows an error.
And also i'm not sure how to let guice inject different fileName
public interface IFileHandler<T> {
T getContent();
}
and
public class JsonFileHandler implements IFileHandler<T> {
String fileName;
#Inject
public JsonFileHandler(String file) {
this.fileName = file;
//Constants.RESULTS_BASELINE_FILE
}
public <T> T getContent() {
T t = null;
ObjectMapper mapper = new ObjectMapper();
try {
t = mapper.readValue(new File(fileName), T.class);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return t;
}
}
For the type variable part, it would be, with this interface:
public interface IFileHandler<T> {
T getContent();
}
this implementing class declaration and method signature:
class JsonFileHandler<T> implements IFileHandler<T> {
public T getContent() {
T t = null;
// ...
return t;
}
}

How to get the object reference of a field of an object using reflection?

Note: Every time I go to type up this question, I think I see something, but it never pans out, so for the third or fourth time.
Synopsis: I am trying to serialize an object that inherits from the base Response class using the Response class, of which the subclass may have non-primitive field types.
The code is as such (warning: large and not elegant), ordered from the specific class (SpecificResponse), as extended from a common class (CommonResponse), which is a concrete implementation of the abstract class (Response), driven by a test program (Program).
// SpecificResponse.java
package com.jdgj.thinking;
public final class SpecificResponse extends CommonResponse {
public String hell;
public int trike;
public short tail;
public SpecificResponse() {
super();
}
}
SpecifcResponse extends CommonResponse:
// CommonResponse.java
package com.jdgj.thinking;
public class CommonResponse extends Response {
public int thing2;
public Value value;
#Override
protected void initialize() {
System.out.println("hello!");
value = new Value();
}
}
For testing purposes, I just made a simple Value object:
// Value.java
package com.jdgj.thinking;
public class Value {
public int five;
}
And, that which does a lot of work, and also the foundation for CommonResponse, the Response class:
// Response.java
package com.jdgj.thinking;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
public abstract class Response {
public static Class<?> fromClassSignature(List<String> signature) throws IllegalArgumentException, IllegalStateException, ClassNotFoundException {
if (signature == null || signature.size() == 0) {
throw new IllegalArgumentException("Null or empty Response class signature.");
}
String lastClassName = null;
for (String line : signature) {
if (line.startsWith("class:")) {
lastClassName = line.split(":")[1];
}
}
if (lastClassName == null) {
throw new IllegalStateException("Could not find the Response class name.");
}
Class<?> c = Class.forName(lastClassName);
lastClassName = null;
Class<?> sc = c.getSuperclass();
while (sc != null && !sc.equals(Response.class)) {
sc = sc.getSuperclass();
}
if (sc != null) {
sc = null;
return c;
} else {
return null;
}
}
protected abstract void initialize();
private String getFieldSignature(Field field) {
return "field:" + field.getName() + "|" + field.getType().getCanonicalName();
}
private List<String> serializeObject(Class<?> c, Object o) {
List<String> serialization = new ArrayList<String>(0);
serialization.add("class:" + c.getName());
for (Field f : c.getDeclaredFields()) {
if (!f.isSynthetic() && Modifier.isPublic(f.getModifiers())) {
StringBuilder sb = new StringBuilder(getFieldSignature(f));
Class<?> t = f.getType();
Object value = null;
try {
value = f.get(o);
System.out.println(f.getName() + "=" + value);
if (t.isPrimitive() || t.equals(String.class)) {
sb.append("`" + value.toString() + "");
}
} catch (NullPointerException e) {
if (t.isPrimitive() || t.equals(String.class)) {
sb.append("`");
} else {
System.out.println("UNEXPECTED NULL POINTER EXCEPTION");
}
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
serialization.add(sb.toString());
if (value != null) {
if (!(t.isPrimitive() || t.equals(String.class))) {
serialization.addAll(serializeObject(t, value));
}
}
}
sb = null;
t = null;
}
}
return serialization;
}
private List<String> describeClass(Class<?> c) {
List<String> description = new ArrayList<String>(0);
description.add("class:" + c.getName());
for (Field f : c.getDeclaredFields()) {
if (!f.isSynthetic() && Modifier.isPublic(f.getModifiers())) {
description.add(getFieldSignature(f));
Class<?> t = f.getType();
if (!(t.isPrimitive() || t.equals(String.class))) {
description.addAll(describeClass(t));
}
t = null;
}
}
return description;
}
public final List<String> getSerializedObject() {
Class<?> c = getClass();
List<String> object = new ArrayList<String>(0);
while (c != null && !c.equals(Response.class)) {
object.addAll(0, serializeObject(c, this));
c = c.getSuperclass();
}
c = null;
return object;
}
public final List<String> getClassSignature() {
Class<?> c = getClass();
List<String> signature = new ArrayList<String>(0);
while (c != null && !c.equals(Response.class)) {
signature.addAll(0, describeClass(c));
c = c.getSuperclass();
}
c = null;
return signature;
}
}
These classes are driven by a 'dev-test' program for now:
// Program.java
import com.jdgj.thinking.Response;
import com.jdgj.thinking.SpecificResponse;
public class Program {
private static void printClassSignature(Response response) {
for (String line : response.getClassSignature()) {
System.out.println(line);
}
}
private static void printSerializedObject(Response response) {
for (String line : response.getSerializedObject()) {
System.out.println(line);
}
}
public static void main(String[] args) {
String CN_SPECRSP = "com.jdgj.thinking.SpecificResponse";
Class<?> response = null;
try {
response = Response.fromClassSignature(new SpecificResponse().getClassSignature());
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
if (response != null) {
System.out.println("Expected: " + CN_SPECRSP + "; Actually: " + response.getCanonicalName());
Response rsp = null;
try {
rsp = (Response)response.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (rsp != null) {
//printClassSignature(rsp);
printSerializedObject(rsp);
rsp = null;
}
}
response = null;
}
}
}
}
Here's the output:
Expected: com.jdgj.thinking.SpecificResponse; Actually: com.jdgj.thinking.SpecificResponse
hell=null
trike=0
tail=0
thing2=0
value=null
class:com.jdgj.thinking.CommonResponse
field:thing2|int`0
field:value|com.jdgj.thinking.Value
class:com.jdgj.thinking.SpecificResponse
field:hell|java.lang.String`
field:trike|int`0
field:tail|short`0
Why does value report null?
In both not having and having a constructor defined in CommonResponse to initialize the Value instance, it's still shown as null. If I uncomment the Program.getClassSignature method, the code delves into the Value object to get the five field:
Expected: com.jdgj.thinking.SpecificResponse; Actually: com.jdgj.thinking.SpecificResponse
class:com.jdgj.thinking.CommonResponse
field:thing2|int
field:value|com.jdgj.thinking.Value
class:com.jdgj.thinking.Value
field:five|int
class:com.jdgj.thinking.SpecificResponse
field:hell|java.lang.String
field:trike|int
field:tail|short
hell=null
trike=0
tail=0
thing2=0
value=null
class:com.jdgj.thinking.CommonResponse
field:thing2|int`0
field:value|com.jdgj.thinking.Value
class:com.jdgj.thinking.SpecificResponse
field:hell|java.lang.String`
field:trike|int`0
field:tail|short`0
I feel as if I've exhausted my Google-fu, and I feel like I'm missing something just.. blatantly obvious, but I cannot think of the reason, or the right query to ask Google. Everyone keeps providing ways to get primitive fields, but that is not what I am seeking. I therefore submit to the guidance of SO.
As Holger said you never initialize that field. You have a initialize() method to do it, but never invoke it.
Of course if you call getClassSignature() you get info about your field, actually it's there; you got a field named value of type com.jdgj.thinking.Value in your class, but it never has been instantiated, so that field value is null.

java customize ObjectOutputStream to write additional data for each instance of a specific class

There're some library classes that although implement Serializable, fail to serialize correctly. I can't fix them, but I can extend ObjectOutputStream and ObjectInputStream for some workaround.
I want my ObjectOutputStream to write additional data for each instance of class A and ObjectInputStream to read and apply that data after A is deserialized.
Currently I have a mid-workaround that requires explicit additional calls to writeObject() and readObject(). I'd prefer to manage without these calls.
Uncomment /* */ blocks to see how it works.
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
import org.junit.Test;
import static org.junit.Assert.*;
public class CloneSerializableTest2 {
// library classes
public static class A implements Serializable {
public transient String s1;
}
public static class MyA extends A {
public String s2;
}
/*
private static class AHolder implements Serializable {
private static final Field s1Fld;
static {
try {
s1Fld = A.class.getDeclaredField("s1");
s1Fld.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Unexpected error", e);
}
}
private String s1;
private A a;
public AHolder(A m) {
this.a = m;
try {
s1 = (String)s1Fld.get(m);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unexpected error", e);
}
}
public void restoreA() {
try {
s1Fld.set(a, s1);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unexpected error", e);
}
}
}
*/
#SuppressWarnings("unchecked")
public static <T> T cloneSerializable(T o) {
try {
/*
final List<AHolder> accumSrc = new ArrayList<AHolder>();
*/
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout)
/*
{
{
enableReplaceObject(true);
}
#Override
protected Object replaceObject(Object obj) throws IOException
{
if (obj instanceof A) {
accumSrc.add(new AHolder((A)obj));
}
return super.replaceObject(obj);
}
}
*/
;
out.writeObject(o);
/*
out.writeObject(accumSrc);
*/
out.close();
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream in = new ObjectInputStream(bin);
Object copy = in.readObject();
/*
List<AHolder> accumDst = (List<AHolder>)in.readObject();
for (AHolder r : accumDst) {
r.restoreA();
}
*/
in.close();
return (T)copy;
} catch (IOException e) {
throw new RuntimeException("Unexpected error", e);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Unexpected error", e);
}
}
#Test
public void testIt() throws Exception {
try {
MyA m1 = new MyA();
m1.s1 = "a";
m1.s2 = "b";
m1 = cloneSerializable(m1);
assertEquals("a", m1.s1);
assertEquals("b", m1.s2);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
Answering to myself
import java.io.*;
import java.lang.reflect.Field;
import org.junit.Test;
import static org.junit.Assert.*;
public class CloneSerializableTest2 {
// library classes
public static class A implements Serializable {
public transient String s1;
}
public static class MyA extends A {
public String s2;
}
private static class AHolder implements Serializable, Externalizable {
private static final Field s1Fld;
static {
try {
s1Fld = A.class.getDeclaredField("s1");
s1Fld.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Unexpected error", e);
}
}
private String s1;
private A a;
#SuppressWarnings("unused")
public AHolder() {
}
public AHolder(A m) {
this.a = m;
try {
s1 = (String)s1Fld.get(m);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unexpected error", e);
}
}
private Object readResolve() {
try {
s1Fld.set(a, s1);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unexpected error", e);
}
return a;
}
#Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(s1);
ObjectOutputStream out2 = ((ObjectOutputStream)out);
out2.writeUnshared(a);
}
#Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
s1 = (String)in.readObject();
a = (A)in.readObject();
}
}
#SuppressWarnings("unchecked")
public static <T> T cloneSerializable(T o) {
try {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout)
{
{
enableReplaceObject(true);
}
#Override
protected Object replaceObject(Object obj) throws IOException
{
if (obj instanceof A) {
obj = new AHolder((A) obj);
} else if (obj instanceof AHolder) {
obj = ((AHolder)obj).a;
}
return super.replaceObject(obj);
}
};
out.writeObject(o);
out.close();
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream in = new ObjectInputStream(bin);
Object copy = in.readObject();
in.close();
return (T)copy;
} catch (IOException e) {
throw new RuntimeException("Unexpected error", e);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Unexpected error", e);
}
}
#Test
public void testIt() throws Exception {
try {
MyA m1 = new MyA();
m1.s1 = "a";
m1.s2 = "b";
m1 = cloneSerializable(m1);
assertEquals("a", m1.s1);
assertEquals("b", m1.s2);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}

In Java, how to use reflection to get a static method and execute it? [duplicate]

This question already has answers here:
How do I invoke a private static method using reflection (Java)?
(5 answers)
Closed 8 years ago.
I have a bunch of static method names, how do I execute them. I think I can use reflection, but how to do that?
directly from the interwebz
Class<?> class1;
try {
class1 = Class.forName(CLASS);
Method method = class1.getMethod(METHOD, String.class);
Object o = method.invoke(null, NAME);
System.out.println(o);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Code to execute static method:
Method method = Utils.class.getMethod("generateCacheFolderName", Integer.class);
System.out.println(method.invoke(null, new Integer(10)));
and class with static method:
public class Utils {
public static String generateCacheFolderName(Integer len) {
Random rand = new Random();
StringBuilder sb = new StringBuilder(len);
for(int i = 0; i<len; ++i)
sb.append(rand.nextInt() % 10);
return sb.toString();
}
public static String anotherStaticMethod() {
return null;
}
}
static public Object execute( Class<?> cls, Object instance, String methodname,
Object[] args, Class<?>[] types ) throws Exception {
Object result = null;
Method met = cls.getMethod( methodname, types );
if (instance == null && !Modifier.isStatic( met.getModifiers() )) {
throw new Exception("Method '" + methodname + "' is not static, so "
+ "instance must be not null");
}
try {
result = met.invoke( instance, args );
}
catch (InvocationTargetException ite) {
throw (Exception) ite.getCause();
}
return result;
}

Categories

Resources