Spring Integration Object To Map Transformer - spring-integration

I am using SI 4.0 and trying to use object-to-map-transformer as below
<integration:object-to-map-transformer input-channel="inputChannel"
output-channel="outChannel" >
</integration:object-to-map-transformer>
I am sending a object like Person class on the inputChannel. But the moment I fire my test it fails with following error
Caused by: java.lang.IllegalStateException: Neither jackson-databind.jar,
nor jackson-mapper-asl.jar aren't presented in the classpath. at
org.springframework.integration.support.json.JacksonJsonUtils.<clinit>(JacksonJsonUtils.java:41)
I dont understand why it needs jackson. I looked at SI code and can see it needs Jackson class but why is this need - when I simply need to map a simple object to Map?
Thanks

The code to convert object to map looks like:
Map<String,Object> result = this.jsonObjectMapper.fromJson(this.jsonObjectMapper.toJson(payload), Map.class);
Since the out of the box implementation for the JsonObjectMapper is Jackson, it requires that the last one should be presented in the classpath.
We decided to use JSON notation for the Map presentation, since any object in JSON has map-based structure.
If you have another algorithm to do the same, the contribution is welcome!
Or you can simply implement your own Transformer with that logic and use it from generic <transformer>.

Related

How to get ASTNode definition in JDT?

I can get IBinding from a MethodInvocation.getName() and now I want to get the offset of this binding in the CompilationUnit in order to get the definition position. But I can not find any information of this. By the way, I use ASTParser.setSource(char[]) not IJavaProject.
The normal approach in JDT looks like this:
IJavaElement method= methodBinding.getJavaElement();
if (method instanceof IMember) {
ICompilationUnit cu= ((IMember) method).getCompilationUnit();
CompilationUnit compilationUnit= // use ASTParser here...
ASTNode methodDecl= compilationUnit.findDeclaringNode(methodBinding.getKey());
... methodDecl.getStartPosition() ...
}
This, however, requires that the Java Model is available. If you don't have an IJavaProject then #getJavaElement() will probably answer null. In that case you will have to implement your own heuristic for mapping an ITypeBinding (from IMethodBinding#getDeclaringClass()) to a compilation unit.
Put differently: if you want JDT to help locating elements outside the current compilation unit, then using the Java Model is the way to go.
As an alternative to using the full-blown Java Model, you could try parsing all relevant compilation units in one batch (using #getASTs() - plural), and then create your own reverse map from ITypeBinding to CompilationUnit.

How to transform a LinkedHashMap Payload to Object Payload in mule?

I want to transform a LinkedHashMap Payload to Object Payload in mule , i used the Byte Array to Object transformer but it dosent work for me , any idea guys ?
you can use dataweave to transform a payload of generic type (=java.util.Map) to a specific type (foo.bar.Type in the example):
%dw 1.0
%output application/java
---
payload as :object {
class: "foo.bar.Type"
}
You seem to mention specifically the Object type. A LinkedHashMap is already an instance of Object: every Java instances inherit from the root class Object.
If you want to transform your HashMap into a specific object such as JSON or a custom object such as com.mycompany.CompData, you have several possibilities depending on your use case:
use DataWeave as mentioned in other answers (require EE)
use a built-in transformer such as Object-to-JSON
implement your own Transformer by extending AbstractTransformer
Se the docs for details: https://docs.mulesoft.com/mule-user-guide/v/3.8/using-transformers
If you may be more specific as to what your use case is I'll gladly refine my answer ;)
You can use either dataweave or json to object transformer.

JAXB XJC options: Alternative to com.sun.tools.xjc.Options which is Java9-friendly and OSGi-friendly

In our framework we have an interface with this method in the public API:
JaxbConfiguration newJaxbConfiguration(Options xjcOpts);
In the implementation, we do something like this:
import com.sun.tools.xjc.ModelLoader;
import com.sun.tools.xjc.Options;
import com.sun.tools.xjc.model.Model;
...
public JaxbConfiguration newJaxbConfiguration(Options xjcOpts) {
Model model = ModelLoader.load(xjcOpts, ...);
...
}
However, both OSGi and Java 9's jigsaw don't like that we use com.sun.tools.xjc.Options, not in our implementation and especially not in our public API interface.
How can we get rid of it?
The JDeps website lists some of the JDK internal APIs and the recommended way to replace their usage. However, the use of ModelLoader.load() is not mentioned. My guess is that this use case has not come up enough to get the attention of the JDeps team.
My recommendation would be to refactor this method so that
you pass in the data you're using to construct the Options argument, instead of passing in the Options argument
use that data to construct your JaxbConfiguration object instead of converting from the internal Model.
You don't mention what JaxbConfiguration is or what library it's from so it's hard for me to say exactly how to construct it. Anyway, this answer is about how to remove the use of the internal API. How to construct a JaxbConfiguration is probably a different question.

Partial objects with JAXB?

I'm working to create some services with JAX-RS, and am relatively new to JAXB (actually XML in general) so please don't assume I know the pre-requisites that I probably should know! Here's the questions: I want to send and receive "partial" objects in XML. That is, imagine one has an object (Java form, obviously) with:
class Thing { int x, String y, Customer z }
I want to be able to send an XML output that contains (dynamically chosen, so I can't use XmlTransient) just x, or just z, or x and y, but not z, or any other combination that suits my client. The point, obviously, is that sometimes the client doesn't need everything, so I can save some bandwidth (particularly with lists of deep, complex objects, which this example clearly doesn't illustrate!).
Also, for input, the same bandwidth argument applies; I would like to be able to have the client send just the particular fields that should be updated in, say, a PUT operation, and ignore the rest, then have the server "merge" those new values onto existing objects and leave the un-mentioned fields unchanged.
This seems to be supported in the Jackson JSON libraries (though I'm still working on it), but I'm having trouble finding it in JAXB. Any ideas?
One thought that I was pondering is whether one can do this in some way via Maps. If I created a Map (potentially nested Maps, for nested coplex objects) of what I want to send, could JAXB send that with a plausible structure? And if it could create such a map on input, I guess I could work through it to make the updates. Not perfect, but maybe?
And yes, I know that the "documents" that will be flying around will probably fail to comply with schemas, having missing fields and all that, but I'm ok with that, provided the infrastructure can be made to work.
Oh, and I know I could do this "manually" with SAX, StAX, or DOM parsing, but I'm hoping there's a rather more automatic way, particularly since JAXB handles the whole objects so effortlessly.
Cheers,
Toby
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
EclipseLink JAXB (MOXy) offerst this support through its object graph extension. Object graphs allow you to specify a subset of properties for the purposes of marshalling an unmarshalling. They may be created at runtime programatically:
// Create the Object Graph
ObjectGraph contactInfo = JAXBHelper.getJAXBContext(jc).createObjectGraph(Customer.class);
contactInfo.addAttributeNodes("name");
Subgraph location = contactInfo.addSubgraph("billingAddress");
location.addAttributeNodes("city", "province");
Subgraph simple = contactInfo.addSubgraph("phoneNumbers");
simple.addAttributeNodes("value");
// Output XML - Based on Object Graph
marshaller.setProperty(MarshallerProperties.OBJECT_GRAPH, contactInfo);
marshaller.marshal(customer, System.out);
or statically on the class through annotations:
#XmlNamedObjectGraph(
name="contact info",
attributeNodes={
#XmlNamedAttributeNode("name"),
#XmlNamedAttributeNode(value="billingAddress", subgraph="location"),
#XmlNamedAttributeNode(value="phoneNumbers", subgraph="simple")
},
subgraphs={
#XmlNamedSubgraph(
name="location",
attributeNodes = {
#XmlNamedAttributeNode("city"),
#XmlNamedAttributeNode("province")
}
)
}
)
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
For More Information
http://blog.bdoughan.com/2013/03/moxys-object-graphs-partial-models-on.html
http://blog.bdoughan.com/2013/03/moxys-object-graphs-inputoutput-partial.html
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html

"Generic" #XmlRootElement?

I'm working against a very large API, most of whose return values look like:
<{APIMethodName}Resp>
<ResponseCode></ResponseCode>
<ResponseMessage></ResponseMessage>
</{APIMethodName}Resp>
Is there any sort of JAXB fu that will let me do this with just one class? I'm ok if JAXB ignores the root, just throws it away.
Thanks.
You could use the unmarshal method that take a class parameter. This causes the JAXB implementation to ignore the root element.

Resources