non-overrideing jaxb generation - eclipse

I am trying to generate a bunch of xml annotated pojos. To do this I have all my xsd files in the resource folder of my project (they are from the polycom rmx sdk, RmxSdkApiV7_8-EMA_EMA-V7_8_0_303). I then right click on each one (over 150 of them) go to generate and click JAXB classes. I pick the project and give it a namespace than finish the wizard. After doing this there is a warning that any newly generated classes will override existing ones. This is my problem, because some commonly used objects will have different definitions in different xsd files. So when the override happens whatever was defined is lost.
So for example, response_trans_conf.xsd defines GET as
<xsd:element name="GET">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="CONFERENCE" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Where as another schema file like trans_conf_2.xsd defines GET as
<xsd:element name="GET">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="ID"/>
<xsd:element ref="OBJ_TOKEN"/>
<xsd:any processContents="skip" minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
So I'll end up with a Get object that looks like
public class GET {
#XmlElement(name = "CONFERENCE")
protected ConferenceContent conference;
OR (respectively)
public class GET {
#XmlElement(name = "ID", required = true)
protected BigInteger id;
#XmlElement(name = "OBJ_TOKEN", required = true)
protected String objtoken;
#XmlAnyElement
protected List<Element> any;
What I need is an object that a combination of both. Like I said there are over 150 xsd files in this sdk. So this problem is multiplied by few other common objects.
FYI at the same time of wanting a combined class rather then an overridden one Im hoping the solution would also prevent duplicates some how.

due to lack of answers I have implemented a workaround which is to manually add the missing/needed members.
Im sure the comment above by ulab would work as well but I really do not want to edit the xsd's
The other option I see but did not implement is a wrapper. extending these common classes to have all the members in another layer above the sdk's generated file. that would ensure the sdk doesnt need to be touch even when there is a new version and a new generation of files.

Related

WSDL contract list occuring with numbers

When I define the fields of a contract in XSD I define a list field with maxOccurs= and minOccurs>0.
Can i declare the XSD in such a way that when the request is received the fields with occurs have occurance number?
e.g.
I hope i make my self clear.
<xsd:complexType name="FieldNameType">
<xsd:sequence>
<xsd:element name="FieldName" type="FieldNameType" minOccurs="1" maxOccurs="8"/>
</xsd:sequence>
</xsd:complexType>
and when the request is send i get something like:
<FieldName_1></FieldName_1>
<FieldName_2></FieldName_2>
<FieldName_3></FieldName_3>
Thanks in advance!
I found a work-around! As i saw i can iterate through the same nodes in an XSLT file.

Sparx Enterprise Architect - XSD Generation : Importing a XSDschema reference in the generated one

I'm using Sparx Enterprise Architect v10 to generate XSD schema from XML Schema graphic model.
Basically, I created 2 different XSDschema : 1 main XSDshema with my entities that are complexType :
<xs:complexType name="EntitytXT">
<xs:annotation>
<xs:documentation>This is the definition of an EntitytXT</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="element1" type="shared:StringXT" minOccurs="1" maxOccurs="1"/>
<xs:element name="element2" type="shared:StringXT" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
The other created XSDschema is the "shared one" and is simple with just the type StringXT; composed of things like that :
<xs:simpleType name="StringXT">
<xs:restriction base="xs:string">
<xs:maxLength value="5" />
</xs:restriction>
</xs:simpleType>`
What I want to do is :
Whenever I generate the first main XSD with EA, that the imported xsd "shared" path
xmlns:v1shared="http://xxxx/common/v1/shared" AND that the tag
<xs:import namespace="http://xxxx/shared" schemaLocation="http:/xx/xx/common/shared.xsd" />
are present in my generated resulting XSD.
Many thanks.
So, after almost a day, it ended up to be fairly obvious.
I didn't find any specific answer to this practical import procedure for different XSDschema in EA.
The thing is : you have 2 XSDschema as 2 different packages. To ensure the "shared" one to be imported into the main one (with the tag <xs:import explicitly in the xsd header, you must :
Enter 2 different target Namespace, one concerning each XSDschema package
Add the "shared" (+its namespace) in the XMLNS tab within the main XSDschema properties
Double check the SchemaLocation Tagged value for each XSDschema package
And last, but not least, in the xs sequence for your main complexTypes <xs:element name="element1" type="shared:StringXT" the "type" tag must be just :StringXT (without the 'shared') in order to 'link' the main XSDschema and the shared one. You can go to the XSDschema attributes and check their tagged values. You should see something like +Attributes +from StringXT
hope it helps!

JAXB (new) annotation

If you have some Java class:
#XmlType(namespace="")
#XmlRootElement(name="", namespace="")
public class Car
{
// This is some comment
#XmlElement()
private long id;
...
And you want to create schema like this (with comment inside schema):
<xs:complexType name="Car ">
<xs:sequence>
<xs:documentation> This is some comment</xs:documentation>
<xs:element name="id" type="xs:long"/>
</xs:sequence>
</xs:complexType>
Is there way how to configure JAXB?
I have think, is there way how to create "new annotation", so my Java class would look like:
#XmlType(namespace="")
#XmlRootElement(name="", namespace="")
public class Car
{
#XmlDoc("This is some comment")
#XmlElement()
private long id;
...
In other words: can I tell jaxb, that new annotation is important to him and how it should be "parsed" in context.generateSchema (schemaOutputResolver)
(As example: #XmlDoc is new annotation and jaxb should take its value and put in xs: document element)
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
This functionality does not currently exist today, but it has been requested before:
https://java.net/jira/browse/JAXB-273
There is also an open enhancement request where we are gather the requirements to add this type of feature to MOXy. I would be interested in getting your thoughts on it:
http://bugs.eclipse.org/409419

hyperjaxb3 xsd:string length in JPA entity

I use Hyperjaxb3 to generate JPA entities from XSD schema. I have a xsd:string type that I want to use for description text (text area in the UI):
<xsd:complexType name="Description">
<xsd:simpleContent>
<xsd:extension base="**xsd:string**">
<xsd:attribute name="abc" type="xsd:NCName" use="optional" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
Hyperjaxb3 generates class (entity) Description with attribute value, annotated like this:
#Basic
#Column(name = "VALUE_", **length = 255**)
public String getValue() {
return value;
}
The questions I have:
I saw that if I put xsd:maxLength restriction on xsd:simpleType, JPA #Column.length has the value of maxLength. How can I set xsd:rescriction on xsd:simpleContent that is xsd:extension of xsd:string? Do I have to define a complexType with xsd:resctriction that I will extend? And if yes, will Hyperjaxb generate #Column.length by my restriction. I tried following:
<xsd:simpleType name="DescriptionParent">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="4096" />
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="Description">
<xsd:simpleContent>
<xsd:extension base="DescriptionParent">
<xsd:attribute name="abc" type="xsd:NCName" use="optional" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
But the JPA column length is still 255.
Is it also possible to set in my JAXB customization (*.xjb file) the lenght of the column for given type (somehow let hyperjaxb know that this is the orm I want to use for my specific type)? Or is it totally out of the way and xsd:maxLength should be used (above) I managed to set it globally for Hyperjaxb customization:
Thanks for your help.
Second question: yes, you can configure global type mappings for simple types.
See Per-type customization for single properties.
First question: it seems to be a bug/missing feature, please file an issue here.

Why is an XSD element of type s:date becoming a string when generating a Service Reference?

I'm trying to create a new Service Reference from a WSDL and all of the properties I expect to be DateTime instead of string.
For example, this xsd definition for Contact:
<s:complexType name="Contact">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Address" type="tns:Address" />
<s:element minOccurs="0" maxOccurs="1" name="Email" type="s:string" />
...
<s:element minOccurs="1" maxOccurs="1" name="BirthDate" type="s:date" />
</s:sequence>
The type of BirthDate is s:date, but the generated type (in Reference.cs) is a string.
internal partial class Contact : object, IExtensibleDataObject, INotifyPropertyChanged
{
[OptionalField]
private MembershipMgmtMediator.Address AddressField;
[OptionalField]
private string EmailField;
private string BirthDateField;
}
If i create a web project and add it as a Web Reference instead of a Service Reference, it correctly becomes a DateTime. I assume that has something to do with the way wsdl.exe and svcutil.exe work behind the scenes, but regardless, I'm stuck on trying to figure out how to correctly get Visual Studio to recognize that this property should be a DateTime.
There is some good info in these questions: How to generate xs:Date in WCF OperationContract parameter and Best practices for DateTime serialization in .NET 3.5.
As Alex states in his comment to the question, WCF does not support xs:date types. However, it is perhaps more accurate to say that the default DataContractSerializer does not support that type, while the above questions indicate that the XmlSerializer can handle it.
See this link for a DataContractSerializer against XmlSerializer comparison.
If I run:
svcutil http://my_web_site?wsdl /ser:XmlSerializer /d:C:\temp
Then a WSDL fragment like this:
<s:complexType name="Contact">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="BirthDate" type="s:date" />
</s:sequence>
</s:complexType>
Has this class generated:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
public partial class Contact
{
private System.DateTime birthDateField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(DataType="date", Order=0)]
public System.DateTime BirthDate
{
get
{
return this.birthDateField;
}
set
{
this.birthDateField = value;
}
}
}
That svcutil invocation produces two files: Service1.cs and output.config. If I include the code file in the project and add the system.serviceModel bits into the configuration file (i.e., web.config or app.config) I can then call the service as normal. For example:
Service1SoapClient client = new Service1SoapClient("Service1Soap");
var contact = client.GetContact();
This approach is not without disadvantages. The Service1.cs file is markedly different if generated without the /ser:XmlSerializer parameter, where you will get additional classes such as WebMethodNameRequest, WebMethodNameRequestBody, WebMethodNameReponse, WebMethodNameReponseBody and so on. If these classes are important in your interactions with the service, my approach may not work for you.
Edit:
In terms of nullable properties, there is some good information in this question: svcutil.exe - Proxy generated not allowing for nullable fields
To get a property nullable in the generated proxy class, the nillable field needs to be set in the WSDL. So something like this:
<s:element minOccurs="0" maxOccurs="1" name="SomeProperty" type="s:date" nillable="true" />
Would generate a property called public System.Nullable<System.DateTime> SomeProperty in the proxy class.
However in your case you can use the SomePropertySpecified property to indicate the presence or absence of the property. These kinds of properties are generated when you have minOccurs="0".
In terms of date formatting I'm not sure. xs:date values are intended to be yyyy-mm-dd with optional timezone information (w3.org). If Oracle is expecting dates in a different format then I wonder how they can be xs:date values at all.
Is there any documentation or other information you can provide regarding the service you are trying to consume?
Edit 2:
I am a little unclear on exactly what "Dates must be in the database format." means in the Oracle docs. If the type is an xs:date then serializing them to the database format would surely mean that it was no longer an xs:date?
Still, there are some things you try in that regard:
Force XmlSerializer to serialize DateTime as 'YYYY-MM-DD hh:mm:ss'
http://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly
You may need to simply experiment sending a few queries to the web service to see just how this date business affects things.
Are you sure those *IsSpecified parameters aren't there? To use my Contact class above as the example, minOccurs=0 on the BirthDate property would give the Contact class an extra property called BirthDateIsSpecified.
Although I believe nick_w's answer covers the question quite well (and I'm awarding him the bounty), I'm providing the solution I'm going to use in my specific case, where just using XmlSerializer isn't enough. In the end, I think I'm going to go with an extension that converts DateTime objects to string, using a custom format specifier.
public static class SoapUtils
{
public static string ToOraDate( this DateTime? dt )
{
return dt != null ? dt.Value.ToString("dd-MMM-yyyy",
CultureInfo.InvariantCulture) :
}
}
// Calling a service
someDate = DateTime.Now;
service.SomeMethod( someDate.ToOraDate() );
While this is not a real solution, I think that it may work as a workaround. It is dirty and ugly, and I know that, but it may be better than having String in your code.
Since your own classes (like Address) are properly processed, you could build a simple wrapper around Date class that you would include in your project and schema. The class would have only a Date property or a field and a getter to it.