Releases: PassionCoreTech/addresstokenizer-core
Releases · PassionCoreTech/addresstokenizer-core
Release list
v0.4.0
Changed — breaking
ParsedAddress's JSON output is restructured. The flat fields (streetName,
buildingName,unit,floor,city,district,state,postalCode),tokens,
and the derivedcountryare no longer serialized at the top level — they move into
a new nestedgeneralobject (general.countryCode,general.streetName, etc.),
built by the newgeneral()accessor.iso20022Resultis promoted from nested inside
diagnosticsto its own top-level JSON section. Code that readsParsedAddressas a
Java object is unaffected (the record's accessor methods are unchanged); code that
serializes it to JSON directly (rather than throughaddresstokenizer-core-sample's
/parseendpoint, which is unaffected — see below) will see a different shape.ParseDiagnostics.confidencechanges type fromdoubleto a newConfidenceBreakdown
record ({parse, gazetteer, final}), so a caller can see the token-coverage confidence,
the pre-penalty gazetteer match tier, and the post-penalty final value side by side
instead of only the final aggregate.ParseDiagnostics.fieldConfidencesandAddressIso20022Result.fieldConfidencechange
value type from a plainDoubleto a newFieldConfidenceEntryrecord
({confidence, penalty},penaltyomitted when none applied) — merges what were two
parallel confidence/penalty maps into one.ParseDiagnostics.subDivisionandtownLocationare removed — both were pure
duplicates ofiso20022Result.ctrySubDvsn/twnLctnNm; read those instead.TokenType.CORRECTED_CITYis removed. Enrichment-corrected values (e.g. a typo'd city
fixed via gazetteer lookup) now replace the token'svaluein place, with the
as-parsed value preserved on the same token's neworiginalfield, rather than
appearing as a second, separately-typed token.addresstokenizer-core-sample'sGET /parseresponse reshapes from
{raw, country, tokens: [{type, value}]}to{raw, tokens, diagnostics}.diagnostics
is always present (nevernull); on this free tier onlyconfidence(parse/
gazetteer/finalall equal — no gazetteer tier to report) andneedsRevieware
populated, matching the shape Pro's/parsereturns with those two fields always
populated the same way.
Added
AddressTokengains anoriginalfield carrying the as-parsed value when enrichment
replaced it (see theCORRECTED_CITYremoval above);nullwhen the token'svalue
is unchanged from parsing. A new 4-argument constructor is available; the existing
2- and 3-argument constructors are unchanged.ParsedAddress.general()andParsedAddress.iso20022Result()accessor methods, and
three new model types backing them:GeneralView,ConfidenceBreakdown,
FieldConfidenceEntry.
Fixed
ParsedAddress.countryName()threwIllformedLocaleExceptionfor any address that
resolves country to a non-ISO value (e.g. the"UNKNOWN"detection-failure sentinel)
— now returnsnullinstead.AddressTokenizer.parse()'s parse confidence could exceed 1.0 for an address with a
corrected city (the confidence calculation counted mandatory-type token occurrences
rather than distinct types present, so a second same-type token could inflate the
score) — now counts distinct types.CountryDetector.detect()could resolve the wrong country at high confidence when two
country names of equal length both appeared in the address text (e.g. an address
mentioning "Hong Kong" twice as unrelated proper nouns, with "Australia" appearing once
as the actual trailing country declaration, previously resolved toHKinstead of
AU). The equal-length tie-break now prefers whichever name appears closer to the end
of the string, matching mailing-address convention; the existing longer-name-wins rule
is unchanged. Same fix applied todetectInTail().AuAddressParserdropped the suburb entirely when no comma separated it from the street
(e.g."... 80 Druitt Street SYDNEY NSW 2000 ...", a common valid AU layout) —CITY
is now also read from the text immediately following the street type when no
comma-delimited city segment was found.AuAddressParser's unit/suite value truncated at the first.(e.g."Suite 14.02",
AU's floor.unit-style suite numbering, came out as"Suite 14"with".02"leaking into
the street name) — the value now retains dots.AuAddressParseronly ever captured the first unit-like prefix (Unit/Level/Suite/
etc.) — a stacked second prefix (e.g."Suite 14.02, Level 14, ...", restating the
level already encoded in the suite number) leaked into the street name instead of being
part ofUNIT.UNITnow collects every stacked prefix into one value
("Suite 14.02, Level 14").
v0.3.0
Added
CountryDetectorInterfacegainsdetectInTail()— a fuzzy scan of an address's
trailing tokens for a recognized full country name — anddetectDeclaredCountryCode()
— matches a bare 2-letter country code standing alone in the address's final
comma-delimited segment. Both are used to reconcile a raw address's literal country
declaration against the resolvedcountryCode.AddressTokengains an optionalsource()field recording provenance for values not
parsed directly from the raw input (e.g."postal derived"for a Pro-tier city value
looked up from the postal code). The existing two-argument constructor is preserved,
so no source changes are required for direct construction.
Changed
AddressTokenizer.parse()'s parse confidence now applies a small penalty when an
address's literal declared country conflicts with the resolvedcountryCode(e.g.
"350 Fifth Avenue, New York, NY 10118, CA"declaresCAbut resolves toUS) —
previously this conflict was silently discarded and had no effect on confidence.
Fixed
- US, UK, AU, and CA address parsers no longer misread a redundant trailing
self-reference to their own country (e.g."...London, UK","...Melbourne, Australia") as theCITYtoken. addresstokenizer-core-sample: the README's license section incorrectly stated
AGPL-3.0-or-later; corrected to Apache-2.0, matching the module's actual license.
v0.2.1
What's Changed
- Fixed Canadian address parsing for unit values written as
Suite #123in addition toSuite 123. - Added Core-only tests for named accessors on FR, AU, and CA addresses.
- Clarified Core parsing limitations and ISO 20022/CBPR+ disclaimer text in public API docs.
Verification
mvn package(24 tests, 0 failures)
v0.2.0 — unified Core/Pro parsing API
v0.2.0 — unified Core/Pro parsing API
Breaking change from v0.1.0 (allowed pre-1.0 under the published API-stability disclaimer).
What changed
ParsedAddressreshaped. Parsed fields (streetName(),city(),postalCode(),country(), …) are now first-class record components with named accessors, replacing the previous token-map-centric shape. Code that read tokens positionally must switch to the named accessors.- New
AddressParsingServiceinterface.AddressTokenizernow implementsio.passioncore.addresstokenizer.AddressParsingService(parse(String)/parseLines(List<String>)). This is the same interface implemented by the commercial Pro tier'sAddressEnrichmentService— upgrading from Core to Pro is a bean swap with no application-code changes. See the README's "Upgrading from Core to Pro" section. - New model types:
ParseDiagnostics(onParsedAddress.diagnostics()),AddressIso20022Result,CountryCodeStatus,FieldCorrection,TraceLog. - Added
jackson-annotations(annotations only, no databind) so JSON serialization ofParseDiagnosticsdrops null/absent fields.
Full details in CHANGELOG.md.
Supported countries
US, UK, DE, FR, AU, CA (including Quebec French address formats).
API stability
The parsing engine is production-quality for the supported countries; the public API shape may still evolve before v1.0. For production deployments or enterprise licensing contact dev@passioncore.io.
Usage
See addresstokenizer-core-sample for a runnable Spring Boot example.
v0.1.0 — Initial Public Release
Release notes:
Address Tokenizer Core v0.1.0
Free, open-source address tokeniser for Spring Boot applications. Parses free-text postal addresses into structured tokens with no database, no REST layer, and no third-party data subscriptions.
What's included
7 supported countries / locales
- 🇺🇸 United States (USPS format — ZIP, state, unit, floor)
- 🇬🇧 United Kingdom (Royal Mail — postcode at end)
- 🇩🇪 Germany (house number after street name)
- 🇫🇷 France (Rue, Avenue, Boulevard; CEDEX support)
- 🇦🇺 Australia (state abbreviation + 4-digit postcode)
- 🇨🇦 Canada (province code + alphanumeric postal code)
- 🇨🇦 Quebec French (Rue, Boul, Ave detection)
Core features
- Named field accessors:
city(),streetName(),buildingName(),postalCode(),state() - Basic parse confidence score (
parseConfidence) - SWIFT Basic Latin charset normalisation (ä→ae, é→e, ñ→n) for pacs.008 compliance
- Spring Boot auto-configuration — zero setup required
- Works without Spring via direct constructor wiring
- Extensible via
AddressParserSPI — add your own country parser as a Spring bean
Installation
<dependency>
<groupId>io.passioncore</groupId>
<artifactId>addresstokenizer-core</artifactId>
<version>0.1.0</version>
</dependency>
API stability notice
This is an early release. The parsing engine is production-quality for the supported countries. The public API may evolve before v1.0 while a unified Core/Pro interface is being finalised.
Pro edition
Gazetteer enrichment (IATA, GeoNames, OurAirports), ISO 20022 / pacs.008 structured output, weighted confidence scoring, trace logs, and additional country parsers (HK, SG, JP, BR) are available in the commercial Pro edition.
Contact: dev@passioncore.io