Is it possible to unmarshall a class without knowing it's type (JAXBContext.newInstance(clazz)) , or what is proper way to test what is comming?
I do get messages for unmarshaling from plain text - String
Incomming classes doesn't implement any interface and can be in any package.
thanks
No, not really. The JAXB context needs some information about what classes should be bound to. if necessary, pass a list of every possible JAXB-annotated class to the context factory method.
This shouldn't be a limitation, though - your own code also needs to know what classes to expect. If your code doesn't know or care about the type of the bound classes, then JAXB isn't the tool for the job, you should just be unmarshalling into a generic DOM of some kind.
Try to locate your classes, which can come in xml in one package and then pass the list of it to JAXBContext.
Related
I would like to create a class, which would be loadable and saveable to an XML file. I want to use one class which is doing the loading task and I want to integrate it with the actual class that I want to save and load, everything seems to be doable up to the point where JAVA doesn't allow the class instance to be change from within the class, i.e. there is no:
this = JAXBLoader.load();
So currently that's the problem I'm facing.
And I want to be able to control the loading and saving it via the public methods from the class itself, so that from the outside I don't need any factories or managers to load it. Currently the only solution I've seen to this was if I extended the class that I want to save as an xml and then delegate all the methods to the intance of the actual class and then when loading a new instance from the file, the instance would get replaced. But it is a bit of overhead to have to delegate all of the methods, especially pain in the ass if you need to add new methods to the class and have multiple implementations...
So are there any good practices or patterns on achieving something similar or solving the problem I demonstrated above? Actually I'm open, if somebody can overall share what are the best ways to do class saving and loading the easiest ways I would really glad about it.
I'm not quite sure why do you want to avoid external factories and managers. For me it seems quite natural to extract serialization and not handle it in the model classes themselves. But okay.
What I understood is that your core problem is to load data into this instance. Here's a simple way to achieve this with JAXB.
I'm the author of JAXB2 Basics, a plugin package for JAXB/XJC. It contains the copyable plugin which generates a few copyTo methods in the schema-derived classes.
This will give you methods like copyTo(Object target). With this you can first unmarshal data from XML into some temporary instance and then copyTo(this). Something like:
MyType temporaryInstance = unmarshaller.unmarshal(source, MyType.class).getValue();
temporaryInstance.copyTo(this);
You can add this method to your schema-derived code via code injection or by subclassing.
Following my previous question about serialization only, I'd like to go further and support JsonFormatVisitor.
I have the same requirements, that is:
I have objects of several types (interfaces).
I don't know the type of theses objets in advance.
I can't add annotations on theses types.
I can introspect all theses objets to get their state data.
Now that serialization works, I need to generate JsonSchema and hence do something like that:
SchemaFactoryWrapper visitor = WHAT?
mapper.acceptJsonFormatVisitor( mapper.constructType( Foo.class ), visitor );
JsonSchema jsonSchema = visitor.finalSchema();
String schemaString = mapper.writeValueAsString( jsonSchema );
I've implemented a SchemaFactoryWrapper that gets its expectAnyFormat called but I don't know what to do inside it. Looks like there's no schema for "any" objects.
Maybe I can hook elsewhere in jackson? Maybe it is possible to extends the whole Bean/Property introspection mechanism to support a completely different model (ie. not beans)?
I'm a bit lost, please help me find the treasure room :)
I can try to suggest some approaches that may be helpful.
First, even if you can not annotate classes directly, "mix-in annotations" can help -- this does assume static knowledge, however
Second, since schema-generation uses type detection used for serialization, you may want to register custom serializers; but this does not necessarily mean having to hand-write all. The most flexible way to register custom serializers is via Module interface (mapper.registerModule(new MyModule()); Modules can register Serializers instance which gets called when trying to locate a JsonSerializer for a type for the first time (after this, instance is cached to be re-used for other properties of same type).
This is where you could configure and return your custom JsonSerializer; but it might only need to handle schema-related callback(s) (one(s) called by schema generator).
It is also possible to extend/modify property discovery mechanism; whether this is easier depends. But the thing to look for is registering BeanSerializerModifier via Module.
It gets called during construction of BeanSerializer (general POJO serializer used unless something more specific is registered), and with it you can add/modify properties; or just replace resulting serializer altogether (and also then allows chaining of custom serializer with default one, if needed).
I know that I can compile multiple xsd files in a single jar. I've tried using different namespaces which only takes me half way through my goal. This way I can parse the correct schema but I want this to be transparent to my users which will receive the xmlBeans object that I've parsed.
They don't have to know which version of xml file is currently present on the system. I would need a super class for every xsd version to achieve this.
Could this be done with xmlBeans?
My understanding is, if you have a com namespace and a com.v1 and com.v2 namespace and you have an xsd element called EmployeeV1 in com.v1 and EmployeeV2 in com.v2.
You want to a super class called Employee in the com namespace which you want to return to your caller?
Do you think EmployeeV1 and EmployeeV2 could extend from Employee in your xsd? Then maybe when you generate you will get the class hierarchy that represents your xsd.
If that doesn't work, (i haven't used xmlbeans in years now), you might have to create your own domain object and make your callers consume that. That might be worth the effort, since to me it looks like you handle the parsing of an XML that other people rely on, you could abstract all other users from the structure of the XML (which is in flux) by having an intermediary domain object.
Theres a work around to have jaxb handle interface classes by annotating your service Impl class with:
#XmlSeeAlso ({SomeImplClass.java})
and annotating the interface file with:
#XmlRootElement
#XmlJavaTypeAdapter(AnyTypeAdapter.class)
however, this is a problem for me since the interface i'm using isn't editable and creating an Impl class for it is not doable since the interface has tons and tons of nested interfaces.
Is there a solution or workaround for this?
If you think from the JAXB perspective: It marshalls and unmarshalls the JAVA classes to XML, so there cant be any workaround to this.
As if I am JAXB and some one provided me an interface to marshall then I would have to guess which concrete implementation the user is referring to and it cannot do that. That's why I don't think it will be possible.
Need to serialize java objects to JSON while doing compression such as name change, exclusion etc. Objects use class from jar, source code of which is not available.
Looked through many libraries(Jackson , Gson), but found none solving this particular problem. Most of them are annotations based, which I can't use given I don't have source code.
One way to solve this problems is, use reflection and recursively go through object until you find a property name of which should be replaced or object is excluded in serialized JSON.
Need solution for this. Better if it is already implemented and tested.
You can also have a look at Genson library http://code.google.com/p/genson/.
You can rename and filter with quite concise code:
// renames all "fieldOfName" to "toName", excludes from serialization
// and deserialization fields named "fieldNamed" and declared in DefinedInClass
// and uses fields with all visibility (protected, private, etc)
Genson genson = new Genson.Builder().rename("fieldOfName", "toName")
.exclude("fieldNamed", DefinedInClass.class)
.setFieldFilter(VisibilityFilter.ALL)
.create();
genson.serialize(myObject);
If you want to do some more complex filtering (based on annotations for example) you can implement BeanMutatorAccessorResolver or extend BaseResolver.
Same for property renaming you can implement PropertyNameResolver and have full control.
And finally if you want to filter fields, methods or constructors according to their modifiers you can define your own VisiblityFilter.
Concerning performances of filtering/renaming there should be no problem as it is done only once per class and then cached.
To start using Genson you can have a look at the Getting Started Guide.
Found solution to the problem.
Google gson has class called GsonBuilder which has methods for exclusion strategy and naming strategy.
Using these two methods implemented a custom solution, where all the mapping and exclusion rules are stored using a xml and used at the time of serialization and de-serialization.
Works perfectly, though not sure about the performance of same.