Skip to content

Upgrade to NeTEx 2.0 schema for 1.x branch (Java EE 8) - #277

Open
vpaturet wants to merge 15 commits into
1.xfrom
upgrade-netex-2.0_for_1.x
Open

vpaturet wants to merge 15 commits into
1.xfrom
upgrade-netex-2.0_for_1.x

Conversation

@vpaturet

@vpaturet vpaturet commented Mar 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Upgrade the NeTEx schema from version 1.16 to 2.0 on the 1.x line (Java 8, Java EE 8 / javax.xml.bind), as the Jakarta line does in #270. The Maven coordinates (org.entur:netex-java-model) and the org.rutebanken.* packages are unchanged; the version becomes 1.1.0-SNAPSHOT.

The applicable changes of #270 are integrated. Changes that need Java 11+ or Jakarta EE (JPMS module, CXF XJC 4.x / type-safe enums, JUnit 6, Java 21 CI, text blocks) are not ported.

Breaking changes

  1. Generated model API follows NeTEx 2.0 (see "Test updates" for the main differences callers will hit).
  2. xs:date is mapped to java.time.LocalDate instead of LocalDateTime at midnight, e.g. OperatingDay.calendarDate, DayTypeAssignment.date, ServiceCalendar.fromDate/toDate. xs:dateTime is still LocalDateTime. The adapter accepts and ignores an optional time zone offset on input (2026-05-03+02:00, 2026-05-03Z), always writes yyyy-MM-dd, and no longer depends on the JVM's default offset.
  3. NeTExValidator can no longer be constructed directly. Both constructors are private; use NeTExValidator.getNeTExValidator() or getNeTExValidator(NetexVersion), which cache one validator per version. NetexVersion.v2_0 is added and is LATEST.
  4. OmitNullsToStringStyle is final with a private constructor; use OmitNullsToStringStyle.INSTANCE.
  5. The cxf-xjc-runtime transitive dependency is gone. The generated code never referenced it. The remaining runtime dependencies are jakarta.xml.bind-api 2.3, jaxb-java-time-adapters, jaxb-runtime, slf4j-api and commons-lang3.

Changes

NeTEx 2.0 schema

  • The 2.0 XSD is downloaded from the TransmodelEcosystem/NeTEx repository (tag v2.0, previously entur/NeTEx master).
  • The 1.16.1 schema is downloaded from the Entur fork as a legacy validation schema, like 1.15 and earlier. NetexVersion.v1_16 validates against it (patch releases are backward compatible and documents only declare the minor version). Without this, v1_16 had no schema to load once the model moved to 2.0.

JAXB bindings (bindings.xjb)

  • xs:date → java.time.LocalDate via a rewritten LocalDateXmlAdapter (breaking change 2)
  • The _Dummy suffix of the NeTEx 2.0 substitution-group heads is hidden. NeTEx 2.0 names its abstract heads DayType_Dummy where 1.16 used DayType_, and xjc leaked that into getDayType_Dummy(), createDayType_Dummy() and classes such as MediumAccessDevice_Dummy. A generated block in bindings.xjb (from bin/generate-dummy-bindings.py, to be rerun after a schema upgrade) renames them: containers expose getDayType() / getDayTypeRefOrDayType(), ObjectFactory exposes createDayType_(...) and the few classes generated for heads keep a trailing underscore (MediumAccessDevice_), as in 1.0.x. The block is identical to the one in Upgrade to NeTEx 2.0 schema #270.
  • Removed obsolete HeadwayJourneyGroupGroup/Description binding (element removed in 2.0)
  • Added bindings to resolve ObjectFactory name collisions for bookingArrangements vs BookingArrangements

Adapters

  • LocalDateTimeISO8601XmlAdapter and LocalTimeISO8601XmlAdapter: the parseDefaulting(OFFSET_SECONDS, <JVM default offset>) had no effect and is removed; an offset in the input was and is ignored. Results are unchanged.

Test updates

  • MultilingualString now uses mixed content (withContent()/getContent() instead of withValue()/getValue()); helper getStringValue(MultilingualString)
  • Collection getters lose the trailing underscore (e.g. getLine_() → getLine()); factory methods keep it (createLine_())
  • StopPlacesInFrame_RelStructure returns List<StopPlace> directly instead of wrapped JAXBElements
  • AllVehicleModesOfTransportEnumeration → AllPublicTransportModesEnumeration
  • PublicCode and PrivateCode are structure types with getValue()
  • Removed DatedCall tests replaced with AvailabilityCondition tests
  • New LocalDateXmlAdapterTest; UnmarshalServiceCalendarFrameTest asserts LocalDate; NeTExValidatorTest covers LATEST, the 1.16 → 1.16.1 mapping and the 1.16.1-only AssociatedContract element

Other

  • deploy.yml: can be triggered manually (workflow_dispatch). Temporarily builds on push/PR to upgrade-netex-2.0_for_1.x and publishes snapshots from that branch, so that 1.1.0-SNAPSHOT is available before the merge.
  • The manual (fallback) release workflow builds with Java 8 / Temurin like the other 1.x workflows (it still set up Java 11).
  • Pre-JReleaser relics removed from the pom: the jfrog snapshot repository, the wagon-ssh-external extension, the maven-release-plugin configuration, the sign and release profiles (GPG signing and the decommissioned oss.sonatype.org staging) and unused plugin version properties. .gitignore entries for unused plugins dropped.
  • mvn clean now deletes src/main/resources/xsd, so stale schema folders from earlier builds (1.16) no longer end up in locally built jars.
  • README.md and CLAUDE.md updated for NeTEx 2.0 and the 1.x baseline.

Not integrated from #270

  • Maven coordinates / package rename to netex2-java-model / org.entur.netex2 (kept as is for now)
  • JPMS module-info.java, Java 21 baseline, JUnit 6, CXF XJC 4.2 (type-safe WeekOfMonthEnumeration/CurrentTypeEnumeration), Sonar test cleanups relying on Java 15+ syntax

Before merging

  • Restore the 1.x triggers and the refs/heads/1.x snapshot condition in deploy.yml.

Testing

mvn clean install with Java 8 passes: 28 tests, 0 failures. The built jar bundles the 1.04beta - 1.15, 1.16.1 and 2.0 schemas.

vpaturet added 15 commits March 6, 2026 11:42
The NeTEx GitHub repository moved from NeTEx-CEN/NeTEx to
TransmodelEcosystem/NeTEx.
With the model generated from NeTEx 2.0, the 1.16 schema was no longer
downloaded, so NetexVersion.v1_16 could not load its schema. The 1.16.1
schema is now downloaded as a legacy validation schema like 1.15 and
earlier. A document declaring 1.16 is validated against it: patch
releases of the schema are backward compatible and documents only ever
declare the minor version.
xsd:date elements (OperatingDay/CalendarDate, DayTypeAssignment/Date,
ServiceCalendar/FromDate and ToDate, ...) were previously bound to
LocalDateTime at midnight. They are now bound to LocalDate.

LocalDateXmlAdapter accepts an optional trailing zone offset when
unmarshalling, as permitted by xsd:date, and ignores it. Dates are always
marshalled as yyyy-MM-dd and no longer depend on the JVM's default offset.
xsd:dateTime elements are still bound to LocalDateTime.
parseDefaulting(OFFSET_SECONDS, <JVM default offset at class load>)
had no effect: LocalDateTime.from and LocalTime.from never read the
offset, so an offset in the input is ignored whether it is present,
absent or defaulted. Parsing and formatting results are unchanged.
The adapters now document that behaviour, as LocalDateXmlAdapter
already does.
Instances are cached per version and obtained through the static
getNeTExValidator methods, which the constructor Javadoc already asked
callers to use. PublicationDeliveryClient now uses the cached validator.
The style is only meant to be used through INSTANCE. This also removes
the javac this-escape warning about the overridable setters called
from the constructor.
The generated code references nothing under org.apache.cxf: the
toString plugin uses OmitNullsToStringStyle from this library. The
runtime-scoped jar was only leaked to consumers.
Releases and snapshots are published by JReleaser through the GitHub
workflows. The jfrog snapshot repository, the wagon-ssh-external
extension, the maven-release-plugin configuration, the sign and release
profiles (GPG signing and the decommissioned oss.sonatype.org staging)
and the unused nexus-staging, gpg, release and dependency plugin version
properties are left over from the previous release process.
The build only removes the schema folders it is about to download
again, so folders from earlier builds (1.16) ended up in locally built
jars.
maven-release-plugin, buildnumber-maven-plugin and maven-shade-plugin
are not used, so their backup and output files never appear.
… Java 8

deploy.yml can be triggered manually (workflow_dispatch). The manual
release workflow still set up Java 11, while every other 1.x workflow
builds and publishes with Java 8.
State the NeTEx 2.0 schema and its source, the legacy validation range,
the LocalDate mapping, the Java 8 / Java EE 8 baseline and the
GML and SIRI packages. The README gains the usage, build and structure
sections of the master README, with the 1.x coordinates.
CXF XJC 4.x generates Jakarta XML Binding code and JUnit 6 requires
Java 17; the 1.x line targets Java 8 and Java EE 8.
NeTEx 2.0 names its abstract substitution-group heads with a _Dummy
suffix (DayType_Dummy is the head of DayType), where 1.x used a trailing
underscore. xjc leaked the suffix into the generated API as
getDayType_Dummy(), getDayTypeRefOrDayType_Dummy(), createDayType_Dummy()
and classes such as MediumAccessDevice_Dummy.

Add bin/generate-dummy-bindings.py, which derives one JAXB binding per
leak from the schema and writes them into a marked block of bindings.xjb:
properties drop the suffix (getDayType(), getDayTypeRefOrDayType()),
while factory methods and the few classes generated for heads keep a
trailing underscore as in netex-java-model 1.0.x (createDayType_(),
MediumAccessDevice_), since dropping it there collides with the factory
method of the concrete element.

The hand-written TariffZone binding is covered by the generated block.
Tests and docs are updated accordingly.
vpaturet added a commit to entur/chouette that referenced this pull request Oct 15, 2026
The latest 1.1.0-SNAPSHOT (entur/netex-java-model#277, porting #270) hides
the _Dummy suffix of the NeTEx 2.0 substitution-group heads, so the
collection getters revert to their plain names (getLine(), getDayType(),
getNoticeAssignment(), ...).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant