I'm using the Apache BeanUtils setProperty method to import data from an Excel file in a generic manner. I provide the parser a list of "colum name" and "property name" pairs and then the parser sets the properties with setProperty( ..., "property name", ...) for the Excel fields that match with "column name". It's working nice but now I'm having a problem, I have a property that is setted with an addXXX() method and I cannot change that class.
How can I set this property without changing this class or the parser?
Is it possible?
Can I make something like a wrapper with DynaClass, PropertyUtils or MethodUtils so when setting that property it calls the addXX method?
Thanks!
You can write a decorator bean class that will wrap around your class and provide a setXXX() method delegating to addXXX() of the wrapped bean. You can even do that via dynamic proxy with help of cglib or any other bytecode instrumentation library.
If you'd rather go the DynaClass way, take a look at WrapDynaClass as a starting point. You'll have to extend it to provide custom PropertyDescriptor for your method. I wouldn't do this, though, for two reasons - first, addXXX() semantics is likely quite different from setXXX(); and secondly, the whole DynaClass/DynaBean internal API is a bit messy whereas writing your own decorator class is very straightforward.
Related
I would like to implement my own Universal Binary JSON Specification-like specification. As one of my first steps I would like to have a method, which takes an object as parameter, like Gson does in its String com.google.gson.Gson.toJson(Object src) method. So I would like to know the fields and the data types of them. As far as I know does Gson use reflection to achieve that.
Another "solution" could be Serialization. But it's maybe tough to extract the fields from there, and I would prefer anyway, that it's not a must for the object to implement Serializable.
Is Reflection the way to go with my intentions?
You may consider bean introspection (see java.beans.Introspector) for a cleaner, albeit more limited approach.
If your objects are not pure beans (i.e. you need to map fields without getters or setters), you need to use reflection.
I need to create an XSD from some POJOs, most of which do not have a no-arg constructor. JAXB requires a no-arg constructor, hence my exclusion of JAXB from consideration. I don't own the code to the POJOs, so I can't go retrofit them (which also means I can't add any annotations).
Outside of rolling my own XSD generator via reflection introspection, is there some other method for generating XSDs from POJOs? You'd think the googles would reveal lots of tools, but so far my search skills haven't come up with anything. Every plugin/tool seems to use JAXB.
look at this tool see if it will do what you want:
http://80.127.98.91:6060/internal/doc/ssj/devguide_java2schema.html
Sorry in a hurry, but there used to be a java2wsdl tool built under the apache axis project that would generate wsdl, which includes the xsd for the objects used by the interface. There may be something there to look for. It used to work really well.
this may be a better tool: http://xmlbeans.apache.org/
got to run.. hope this helps.
Take a look to Axis2 tools maybe it's not using JAXB but standard constructor with no-org maybe needed.
http://axis.apache.org/axis2/java/core/tools/index.html
I think that's not a big deal to add no-arg constuctor to your classes.
Anothor way with standard JAXB tools : https://docs.oracle.com/javase/tutorial/jaxb/intro/j2schema.html
Part "j2s-xmlType Example" :
A class must have either a public zero-argument constructor or a static zero-argument factory method in order to be mapped by this annotation. One of these methods is used during unmarshalling to create an instance of the class. The factory method can be located within in a factory class or the existing class.
There is an order of precedence as to which method is used for unmarshalling:
If a factory class is identified in the annotation, a corresponding factory method in that class must also be identified, and that method will be used.
If a factory method is identified in the annotation but no factory class is identified, the factory method must be located in the current class. The factory method is used even if there is a public zero argument constructor method present.
If no factory method is identified in the annotation, the class must contain a public zero argument constructor method
So you can create factories.
I'm using Jersey 1.x here and I have a #POST method that requires sending over a deeply nested, complex object. I'm not sure of all my options, but it seems like a lot are described in this documentation:
In general the Java type of the method parameter may:
Be a primitive type;
Have a constructor that accepts a single String argument;
Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String) and
java.util.UUID.fromString(String)); or
Be List, Set or SortedSet, where T satisfies 2 or 3 above. The resulting collection is read-only.
Ideally, I wish that I could define a method like this:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Path("complexObject")
public void complexObject(#FormParam("complexObject") ComplexObject complexObject) throws Exception {
But I guess I can only do that if my object satisfies the requirements above (which in my case, it does not). To me it seems that I have a choice.
Option 1: Implement fromString
Implement item #3 above.
Option 2: Pass in the complexObject in pieces
Break up the complexObject into pieces so the parameters become this:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Path("complexObject")
public void complexObject(#FormParam("piece1") LessComplexPiece lessComplexPiece1,
#FormParam("piece2") LessComplexPiece lessComplexPiece2,
#FormParam("piece3") LessComplexPiece lessComplexPiece3) throws Exception {
This may not be enough if LessComplexPiece does not satisfy the requirements above. I'm wondering what the best option is here. What do people usually do in this situation? Here are the pros and cons I can think of:
Cons of Implement fromString
Have to maintain a custom deserializer. Every time the class is modified, this deserializer may break. There's more risk for bugs in general.
It will probably be impossible to generate documentation that describes the pieces of the complex object. I'll have to write that by hand.
For each piece of the complex object, I'll have to write my own casting and validation logic.
I'm not sure what the post data would look like. But, this may make it very difficult for someone to call the API from a web page form. If the resource accepted primitives, it would be easy. EG: complexObject=seralizedString vs firstName=John and lastName=Smith
You may not be able to modify the class for various reasons (thankfully, this is not a limitation for me)
Pros of Implementing fromString
This could avoid a method with a ton of parameters. This will make the API less intimidating to use.
This argument is at the level of abstraction I want to work at in the body of my method:
I won't have to combine the pieces together by hand (well technically I will, it'll just have to be in the deserializer method)
The deserializer can be a library that automates the process (XStream, gensen, etc.) and save me a lot of time. This can mitigate the bug risk.
You may run into "namespace" clashes if you flatten the object to send over pieces. For example, imagine sending over an Employee. If he has a Boss, you now have to provide a EmployeeFirstName and a BossFirstName. If you were just deserializing an object, you could nest the data appropriately and not have to include context in your parameter names.
So which option should I choose? Is there a 3rd option I'm not aware of?
I know that this question is old but in case anybody has this problem there is new better solution since JAX-RS 2.0. Solution is #BeanParam. Due to documentation:
The annotation that may be used to inject custom JAX-RS "parameter aggregator" value object into a resource class field, property or resource method parameter.
The JAX-RS runtime will instantiate the object and inject all it's fields and properties annotated with either one of the #XxxParam annotation (#PathParam, #FormParam ...) or the #Context annotation. For the POJO classes same instantiation and injection rules apply as in case of instantiation and injection of request-scoped root resource classes.
If you are looking for extended explanation on how this works please look at article I've found:
http://java.dzone.com/articles/new-jax-rs-20-%E2%80%93-beanparam
For complex object models, you may want to consider using JSON or XML binding instead of URL-encoded string to pass your objects to your resource call so you can rely on JAXB framework?
The Jersey Client library is compatible with JAXB and can handle all the marshaling transparently for you if you annotate your classes #XmlElementRoot.
For documentation, XSDs are a good starting point if you choose the XML binding.
Other REST documentation tools like enunciate can take the automatic generation to the next level.
What about special handler which transforms object to e.g. json - kryo if you would prefer performance? You got couple options
Look also at persistence ignorance.
I've just finished reading the chapter of 'Thinking in Java' concerning type information and reflection. While instanceof seems quite natural to me, some examples of reflection made me confused. I want to know if reflection is widely used in Java projects? What are 'the good parts' of reflection? Can you suggest any interesting lectures about reflection and type information with more good and worthy examples?
Edit (one more question):
Why is it useful to access private methods and fields withjava.lang.reflect.Method.setAccesible()?
Thanks in advance.
if you could post some of the examples I would be glad to explain it for you.
Reflection is wildly used with frameworks that need to extract meta-info about the running object (e.g. frameworks which depends on Annotations or the fields in your objets, think about Hibernate, Spring and a lot others).
On a higher layer, I sometimes use reflection to provide generic functionality (e.g. to encode every String in an object, emulate Duck Typing and such).
I know that you already read a book which covers the basics about reflection, but I need to point Sun (erm.. Oracle) official Tutorial as a must read: http://download.oracle.com/javase/tutorial/reflect/
One good example in my opinion is instantiating objects based on class names that are known only at runtime, for example contained in a configuration file.
You will still need to know a common interface to the classes you're dynamically instantiating, so you have something to cast them too. But this lets a configuration drive which implementation will be used.
Another example could be when you have to cast an object to a class that it's a descendant. If you are not sure about the type of that object, you can use instanceof to assure that the cast will be correct at runtime avoiding a class cast exception.
An example:
public void actionPerformed (ActionEvent e){
Object obj = e.getSource();
if (obj instanceof objType)
objType t = (objType) obj; // you can check the type using instanceof if you are not sure about obj class at runtime
}
The reason to provide such features in Reflection is due to multiple situations where tool/application needs meta information of class, variables, methods. For example:-
IDEs using auto completion functionality to get method names and attribute names.
Tomcat web container to forward the request to correct module by parsing their web.xml files and request URI.
JUnit uses reflection to enumerate all methods in a class; assuming either testXXX named methods as test methods or methods annoted by #Test.
To read full article about reflection you can check http://modernpathshala.com/Forum/Thread/Interview/308/give-some-examples-where-reflection-is-used
I would like to create a class in Java based on the fields defined in my XML config file:
For example: if the XML file contains (the syntax has been maligned for posting):
<property name="agent_host"></property>
<property name="subsystem"></property>
then internally it will create a class Event such as Event(String agentHost, String subSystem) that the client can instantiate. Note: the client always knows that this class will be called "Event" but does not know how many "mandatory parameters" it needs to pass.
On the other hand if I have a XML file with:
<property name="agent_host"></property>
then it will create Event(String eventHost) that the client can use for instantiation.
Yes, you could use reflection, but what comes to my mind is working with a class that you could add property.
Imagine a class that has one encapsulated HashMap using a String as a key (for the attribute name) and the value of the attribute so you could read the XML file and for evey property add the attribute to the class like.
For this line:
<property name="subsystem" type="String">value123</property>
GenericClass c = new GenericClass();
c.addAttribute("subsystem", new String("value123"));
//and you could implement a get and set methods like this:
public String getAttributeValue(String attributeName)
{
return internalHashMap.get(attributeName).toString();
}
Using this you could also implement a setAttributeValue
will be quite simple I think
If you really interested in creating a class dynamically, try Byte code Enhancement libraries like BCEL from Apache.
This isn't really a class you want, it's data. Why not use a hashmap? I really dislike "Bean" style classes--they encourage bad coding (there is no place in a generated class to put actual code, so everything ends up being manipulated by external code anyway).
You can just load a hashmap from your XML and inject it into a real object--that way you don't have to worry about actually passing a hash around, you are passing a real object with real business methods and real type safety--it just HAPPENS to use a hashmap internally to store data instead of member variables.
I've done a lot more than this, but at some point you realize Hibernate does everything you want for you.
I think the DynaBean from Commons-BeanUtils may be what you're looking for.
A DynaBean is a Java object that supports properties whose names and data types, as well as values, may be dynamically modified. To the maximum degree feasible, other components of the BeanUtils package will recognize such beans and treat them as standard JavaBeans for the purpose of retrieving and setting property values.