Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with generating enumLeafs #67

Closed
duschata opened this issue May 12, 2016 · 22 comments
Closed

Problems with generating enumLeafs #67

duschata opened this issue May 12, 2016 · 22 comments
Assignees
Milestone

Comments

@duschata
Copy link

I'm using this schema file
`
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://foo.bar.EnumLeafSchema"
targetNamespace="http://foo.bar.EnumLeafSchema"
elementFormDefault="qualified">

<xsd:element name="UsesEnumLeaf">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="personTitle" type="PersonTitleCodesEnumeration"></xsd:element>
<xsd:element name="personName" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:simpleType name="PersonTitleCodesEnumeration">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="mr" />
<xsd:enumeration value="ms" />
<xsd:enumeration value="mrs" />
<xsd:enumeration value="miss" />
<xsd:enumeration value="dr" />
</xsd:restriction>
</xsd:simpleType>

</xsd:schema>
`

This is generated by the compiler:

var enumleafschema_bar_foo_Module_Factory = function () {
  var enumleafschema_bar_foo = {
    name: 'enumleafschema_bar_foo',
    defaultElementNamespaceURI: 'http:\/\/foo.bar.EnumLeafSchema',
    typeInfos: [{
        localName: 'UsesEnumLeaf',
        typeName: null,
        propertyInfos: [{
            name: 'personTitle',
            required: true
          }, {
            name: 'personName',
            required: true
          }]
      }, {
        type: 'enumInfo',
        localName: 'PersonTitleCodesEnumeration',
        values: ['mr', 'ms', 'mrs', 'miss', 'dr']
      }],
    elementInfos: [{
        elementName: 'UsesEnumLeaf',
        typeInfo: '.UsesEnumLeaf'
      }]
  };
  return {
    enumleafschema_bar_foo: enumleafschema_bar_foo
  };
};

But I expected:

localName: 'UsesEnumLeaf',
        typeName: null,
        propertyInfos: [{
            name: 'personTitle',
            required: true,
//This was missing in the generated mapping
            typeInfo: '.PersonTitleCodesEnumeration'
          }, {
            name: 'personName',
            required: true
          }]

Is this a bug? My failure?

Kind regards,

Tom

@highsource
Copy link
Owner

See this:

https://github.com/highsource/jsonix-schema-compiler/blob/master/compiler/src/main/java/org/hisrc/jsonix/compilation/mapping/CreateTypeInfoDeclarationVisitor.java#L167

This is where the typeInfo declaration is generated. If it gives String then it's completely omitted. I'd try return createTypeInfoDeclaration(info); there. I actually have no idea why I didn't do it before. I'm puzzled, but I think it should work.

highsource added a commit that referenced this issue Jun 5, 2016
@duschata
Copy link
Author

I checked a couple of .xsd files containing enums and everything seems to work as I expected. Thanks a lot!

@highsource
Copy link
Owner

Hi,

unfortunately this does not solve the problem completely yet. This works for strings but other types won't work well. We need Java-side conversion between lexical and JSON representation to render enum values correctly.
So don't close it yet.

Best wishes,
Alexey

@benmarch
Copy link
Contributor

Hi there,

I am running into a bit of an issue with this myself. I am able to get the enum values to show up in the mapping.js file, but not in the jsonschema file. Here is what I am seeing in the mapping file:

{
    type: 'enumInfo',
    localName: 'ClassEnum',
    baseTypeInfo: 'NormalizedString',            //I have tried "string" as well
    values: ['standard', 'steps', 'example']
}

And here is the jsonschema file:

"ClassEnum":{
    "allOf":[
        {
            "$ref":"http://www.jsonix.org/jsonschemas/w3c/2001/XMLSchema.jsonschema#/definitions/normalizedString"
        }
    ],
    "typeType":"enumInfo",
    "typeName":{
        "localPart":"classEnum",
        "namespaceURI":"http://blahblahblah"
    }
}

It would be awesome if the schema could have the "enum" property as well:

"ClassEnum":{
    "allOf":[
        {
            "$ref":"http://www.jsonix.org/jsonschemas/w3c/2001/XMLSchema.jsonschema#/definitions/normalizedString"
        }
    ],
    "typeType":"enumInfo",
    "typeName":{
        "localPart":"classEnum",
        "namespaceURI":"http://blahblahblah"
    },
    "enum": ["standard", "steps", "example"]      //this would be the same format as "values" in the mapping except with double quotes
}

Is this something that can be done easily? I could take a stab at a PR if you can point me in the right direction.

Thanks,
Ben

@highsource
Copy link
Owner

It's not quite easy but doable.

Currently, the compiler just associates XML Schema types with names of Jsonix type. That's a simple mapping.

What we need to do is to replace string names with something more intelligent, something like "type descriptor". Type descriptor should be able to parse lexical representations of types and convert then in JSON structures which could then used in mappings and JSON schemas.

You can help by providing sample enumerated simple types for all the simple types for test:

https://github.com/highsource/jsonix-schema-compiler/blob/master/compiler/src/test/resources/basic/zero/schema.xsd

Next, I'll implement type descriptors for a few type and you could help by implementing further type descriptors. Essentially, we have to cover all of the supported types (from CreateTypeInfoDeclarationVisitor).

@highsource highsource added this to the 2.3.x milestone Jul 13, 2016
@highsource highsource self-assigned this Jul 13, 2016
@benmarch
Copy link
Contributor

Thank you for the quick response! I will create a PR with the enum type additions to the sample XSD, but I just want to clarify what you are asking. If I understand correctly, you want me to create a simpleType with a restriction for each of the ~40 simple types? So I would basically stamp out a bunch of these with different base types and values:

<xs:element name="enum" type="enumType"/>
<xs:simpleType name="enumType">
    <xs:restriction base="xs:token">
        <xs:enumeration value="Male"/>
        <xs:enumeration value="Female"/>
    </xs:restriction>
</xs:simpleType>

If that is correct then I can start right away, I was just concerned about the file size blowing up.

@highsource
Copy link
Owner

Right, that would help. Please name them tokenEnum for xs:token etc.
That would help enormously,

@benmarch
Copy link
Contributor

Absolutely, I'll have that done shortly.

benmarch pushed a commit to benmarch/jsonix-schema-compiler that referenced this issue Jul 13, 2016
benmarch added a commit to benmarch/jsonix-schema-compiler that referenced this issue Jul 13, 2016
@benmarch
Copy link
Contributor

Sorry about the duplicate commit, I didn't have my repo configured correctly and it used my work user by mistake. The second one is correct and the corresponding PR is #70.

highsource added a commit that referenced this issue Jul 13, 2016
#67 added enumerable types for all built-in types
@highsource
Copy link
Owner

Thanks a lot!

@benmarch
Copy link
Contributor

No problem, let me know if there is anything else I can do.

@highsource
Copy link
Owner

Seems like we can only support:

  • string
  • boolean
  • float
  • decimal
  • double
  • anyURI

highsource added a commit that referenced this issue Jul 13, 2016
highsource added a commit that referenced this issue Jul 13, 2016
@highsource
Copy link
Owner

I've started the work. It seems like can only generate enum types for a small subset of base types (listed above). This means that if you have an enumeration of dates, this won't be an "enum" type.

But it's still possible to analyze the schema and extract the possible lexical values.

Could you please tell me about your use case a little bit more? This would help to get the right design. How would you use enum values?

@benmarch
Copy link
Contributor

Sure, we currently have two use cases for enums and they are very similar. Our XSD defines the structure of our web content, and we use a templating engine to parse the XML and generate very basic HTML. The HTML contains hooks like dataset attributes and CSS classes based on certain fields in the XML. In one case, we have a field that defines one of three CSS classes (shown in my first comment above) that is applied to a text blob, and in the other case it is a dataset attribute on a div that defines the layout of a pseudo-table. Our legacy content management system can read the XSDs and XMLs and generate HTML forms on the fly so that our content entry teams do not have to write any code. We are in the process of replacing that CMS with our own in-house system and we are using JSONIX to convert the XSDs to JSON Schema, and using Angular Schema Form to generate the HTML forms on the fly. We have had to do some minor alterations to the JSON Schema output because of the way that ASF reads the schemas (it doesn't handle "allOf", "anyOf" or "oneOf", and it does not follow "ref"s) but it does have the ability to read the "enum" property which results in either a HTML select, radio buttons, or checkboxes depending on some settings. I was actually able to pull the "values" array out of the mapping.js file and attach it as an "enum" property in the schema after the schema generation, but I think it would be really helpful if JSONIX would do it while it parsed the XSD.

highsource added a commit that referenced this issue Jul 16, 2016
highsource added a commit that referenced this issue Jul 17, 2016
highsource added a commit that referenced this issue Jul 17, 2016
highsource added a commit that referenced this issue Jul 17, 2016
highsource added a commit that referenced this issue Jul 17, 2016
@highsource
Copy link
Owner

Hi @benmarch, could you please give it a try?

It's not 100% done yet, but I have to wrap up for today. Enum generation in mappings is complete. In JSON schema it generates enum in enum types only, not yet in properties. Enum values are generated according to their types in JSON, so you'll get strings for xs:string, numbers for xs:double, xs:float, xs:decimal and decendants. Also works for types like xs:duration and all the date/time types, ex.:

          {
            name: 'dateTime',
            elementName: {
              localPart: 'dateTime'
            },
            typeInfo: 'DateTime',
            values: [{
                year: 1999,
                month: 5,
                day: 31,
                hour: 13,
                minute: 20,
                second: 0,
                timeZone: -300
              }, {
                year: 2016,
                month: 7,
                day: 13,
                hour: 11,
                minute: 0,
                second: 0,
                timeZone: -300
              }]
          }

For:

    <xs:simpleType name="dateTimeEnumType">
        <xs:restriction base="xs:dateTime">
            <xs:enumeration value="1999-05-31T13:20:00-05:00"/>
            <xs:enumeration value="2016-07-13T11:00:00-05:00"/>
        </xs:restriction>
    </xs:simpleType>

I'd appreciate your feedback before finalizing this.

@benmarch
Copy link
Contributor

Hey @highsource, I think that sounds good, but I would like to test it on my schema if possible. I just tried building the jar but there appears to be a compilation error in master:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project jsonix-schema-compiler: Compilation failure: Compilation failure:
[ERROR] ~/Projects/jsonix-schema-compiler/compiler/src/main/java/org/hisrc/jsonix/compilation/mapping/CreateTypeInfoDelaration.java:[9,33] cannot find symbol
[ERROR] symbol:   class CollectEnumerationValuesVisitor
[ERROR] location: package org.hisrc.jsonix.xml.xsom
[ERROR] ~/Projects/jsonix-schema-compiler/compiler/src/main/java/org/hisrc/jsonix/compilation/mapping/CreateTypeInfoDelaration.java:[53,47] cannot find symbol
[ERROR] symbol:   class CollectEnumerationValuesVisitor
[ERROR] location: class org.hisrc.jsonix.compilation.mapping.CreateTypeInfoDelaration<T,C,M,O>
[ERROR] ~/Projects/jsonix-schema-compiler/compiler/src/main/java/org/hisrc/jsonix/compilation/mapping/CreateTypeInfoDelaration.java:[53,117] cannot find symbol
[ERROR] symbol:   class CollectEnumerationValuesVisitor
[ERROR] location: class org.hisrc.jsonix.compilation.mapping.CreateTypeInfoDelaration<T,C,M,O>

Maybe something wasn't checked in? Please let me know if there is a way I can test your changes.

Thanks,
Ben

highsource added a commit that referenced this issue Jul 18, 2016
@highsource
Copy link
Owner

Sorry, missed a few files. Should be in right now.

@benmarch
Copy link
Contributor

Hey @highsource, it is working perfectly for me. I am able to generate an enum of strings, and it appears in the correct place in the JSON Schema. Thank you!!

@benmarch
Copy link
Contributor

Hey @highsource, any news on when this might be released?

@highsource
Copy link
Owner

Coming this week. There's one small problem to be solved with hierarchican allOfs.

@highsource highsource modified the milestones: 2.3.9, 2.3.x Jul 31, 2016
@highsource
Copy link
Owner

I've decided to leave hierarchical allOf for now.

@benmarch
Copy link
Contributor

benmarch commented Aug 3, 2016

Thanks, @highsource! Works perfectly for me in 2.3.9.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants