Commit 9c348f6
Nested documents UI
Phase 0: EmailArchive nested-document metadata schema (#3660)
Introduces the EmailArchive metadata type as the reference implementation
for Solr nested-document support in RODA — fully config-driven, zero Java.
- emailarchive.xsd: XML schema (parent mailbox + child email elements)
- emailarchive.xslt: ingest crosswalk producing nested Solr child docs via
<field name="emails"><doc>…</doc></field> blocks; follows rakenskapsinfo pattern
- Register type in roda-wui.properties and i18n ServerMessages.properties
- EmailArchiveCrosswalkTest: 12 TestNG tests (full/minimal/no-emails fixtures)
covering parent fields, date fields, child count, multi-value recipients,
and absent-optional-field assertions
Part of: #3382
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat(search): Phase 1 — Advanced AIP Search nested filter groups
Adds `nestedType` and `nestedParentType` properties to SearchField so
config-declared fields can carry a Solr block-join context.
`SearchPanel.buildSearchFilter()` groups all nested-type fields by their
(nestedType, nestedParentType) pair and wraps each group in a
`ParentWhichFilterParameter` — following the RepresentationInformation
pattern — instead of emitting flat filter parameters.
Config registers three EmailArchive child search fields
(emailSubject, emailSender, emailSentDate) as the reference example;
any future nested metadata type benefits automatically through
`roda-wui.properties` alone — no Java changes required.
Note: the implementation uses a `nestedType` property on SearchField
rather than the `nested_group` field type originally proposed in #3661.
This is simpler (no new GWT widget), equally expressive, and avoids
adding a UI rendering path that would be unused for all current types.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat(emailarchive): add title/level to ingest XSLT and HTML dissemination crosswalk
Ingest XSLT now emits `title` (custodian name, emailAddress as fallback)
and a fixed `level = item` so emailarchive AIPs display correctly in the
browse list alongside other AIP types.
New HTML dissemination crosswalk renders all mailbox-level fields with
i18n labels and shows the indexed email messages as a compact table
(subject, sender, sent date, folder).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(emailarchive): use composite title in ingest XSLT
Format: "Custodian <email> (dateStart / dateEnd)"
Date range is omitted when both dates are absent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(emailarchive): add state=ACTIVE to nested email child documents
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adding test for nested documents indexing and search
fix(search): add missing appendANDOperator in block-join filter builders
Without the AND operator prefix, combining AllFilterParameter (*:*) with
ParentWhichFilterParameter or ChildOfFilterParameter produced invalid Solr
syntax (*:*{!parent which=...}) that returned 0 results. Also corrects
inner parseFilterParameter calls to use false since inner builders are empty.
Update CLAUDE.md to reflect that tests use Testcontainers — no docker compose
setup or environment variables required to run tests, only Docker on the host.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(i18n): add missing GWT plural forms across locale files
Add [one] forms alongside existing [=1] forms for de_AT, de_DE, es, pt_PT,
sv_SE — required by GWT for locales where 'one' is a mandatory plural
category. Add [one] and [few] forms for hr (Croatian), which also requires
'few'. Fix hu (Hungarian) by renaming [one] to [=1] since Hungarian uses
DefaultRule which has no 'one' plural category.
Affected keys: selected, representationInformation*, retentionPeriod,
liftDisposalHoldDialogMessage, disposalHoldAssociatedFromValue,
applyDisposalHoldDialogMessage, clearDisposalHoldDialogMessage,
disassociateDisposalHoldDialogMessage, disassociateDisposalScheduleDialogMessage,
disposalPolicySchedule{Day,Month,Year}Summary.
Also adds missing Swedish translation for liftDisposalHoldDialog and
Croatian translation for liftDisposalHoldDialog.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(search): remove space in block-join queries to fix q.op=AND interaction
Solr's standard query parser tokenizes {!parent which=...} and the child
query as SEPARATE clauses when whitespace separates them. With q.op=AND,
the child query becomes a required top-level clause matching child documents
directly, returning 0 AIP results.
Removing the space makes the child/parent filter directly adjacent to the
closing brace, so Solr correctly treats it as the sub-query for the local
params parser: {!parent which=<parentFilter>}<childFilter>.
Extend NestedDocumentSearchTest with a layer-5 assertion that uses
AllFilterParameter + ParentWhichFilterParameter (the production scenario),
covering the *:* AND {!parent ...}<children> query form.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(search): fix block-join query format for q.op=AND compatibility
- Use double-quoted which= local param: `which="field:value"` instead of `which=(field:"value")`
- Use required-operator (+) prefix in child/parent sub-queries: `(+field:"value")`
- Skip AllFilterParameter when block-join params are present to avoid spurious *:* AND prefix
- Add dedicated buildBlockJoinMask() and buildBlockJoinSubQuery() helpers to generate
correct Solr block-join syntax without relying on the standard filter-to-query path
- Add string-level query assertion in NestedDocumentSearchTest (Layer 4) to lock in format
- Update Layer 5 to assert AllFilterParameter is suppressed when block-join is present
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(emailarchive): index dateStart/dateEnd as standard dateInitial/dateFinal fields
Map the email archive date range fields to the standard AIP date fields so they
appear in the existing date range search facet without needing custom Solr fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
revert: remove AllFilterParameter suppression from parseFilter block-join path
The *:* AND prefix produced by AllFilterParameter alongside a block-join query
is functionally harmless — *:* matches every document so intersecting with it
leaves the block-join result unchanged. The specialization was unnecessary.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(search): handle wildcard values in block-join child sub-query builder
Wildcards (* ?) cannot appear inside quoted phrases in Solr's standard query
parser. When a BasicSearchFilterParameter value contains wildcards, emit each
whitespace-separated token as an unquoted +field:token* clause instead of the
phrase-quoted form that was causing SyntaxError.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(search): fix email sent date filter format and selector type
- Change emailSentDate search field type from 'date' to 'date_interval' so the UI
uses a proper from/to date picker and creates DateIntervalFilterParameter with
Date objects rather than SimpleFilterParameter with Date.toString() (which
produces 'Mon Mar 15 00:00:00 GMT+000 2021' — invalid for Solr)
- Add explicit DateIntervalFilterParameter, DateRangeFilterParameter and
LongRangeFilterParameter handlers in buildBlockJoinSubQueryClause to emit
clean +field:[from TO to] range clauses with proper ISO8601 dates instead
of going through the verbose appendRangeInterval fallback
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update Spanish translations
fix(search): exclude nested child documents from normal AIP queries
Solr block-join nested documents (e.g. email children inside an EmailArchive
AIP) were leaking into the normal AIP catalogue search, showing up as
ghost rows with no title/level and navigating to broken child UUIDs on click.
Adds a -_nest_path_:* filter query to all IndexedAIP find/cursor/suggest
paths when ChildOfFilterParameter is not present. Behaviour is also exposed
as a configurable flag:
FindRequest.includeNestedDocuments (default: false)
Clients can set ui.lists.<listId>.includeNestedDocuments = true in
roda-wui.properties to opt-in to receiving nested documents in a specific
list (used by the upcoming virtual catalogue for EmailArchive).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat(catalogue): add virtual catalogue for email archives and individual emails
fix(catalogue): fix email column rendering and enable advanced search in virtual catalogues
- Fix LIST rendering hint bug: recursive call passed LIST hint causing
ClassCastException when inner values are strings; now passes null
- Apply LIST rendering hint to subject_txt so multivalued subjects
display cleanly instead of as Java array toString ([value])
- Apply DATETIME_FORMAT_SIMPLE rendering hint to sentDate_dt for
human-readable date formatting
- Enable advanced search for Search_emailarchive and Search_emails
virtual catalogue tabs
- Add explicit search fields for Search_emailarchive (title,
description, dates) to avoid inheriting nestedType email fields
from the IndexedAIP scope fallback
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(crosswalk): emit dateStart_dt and dateEnd_dt alongside dateInitial and dateFinal in emailarchive crosswalk
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1 parent 860c08f commit 9c348f6
39 files changed
Lines changed: 2346 additions & 947 deletions
File tree
- roda-common/roda-common-data/src/main/java/org/roda/core/data
- common
- v2/index
- roda-core
- roda-core-tests/src/main
- java/org/roda/core
- index
- resources/corpora/DescriptiveMetadata
- roda-core/src/main
- java/org/roda/core/index/utils
- resources/config
- crosswalks/ingest
- schemas
- roda-ui/roda-wui/src/main
- java/org/roda/wui/client/common
- lists/utils
- search
- resources/config
- crosswalks/dissemination/html
- i18n
- client
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
84 | 84 | | |
85 | 85 | | |
86 | 86 | | |
87 | | - | |
| 87 | + | |
88 | 88 | | |
89 | 89 | | |
90 | 90 | | |
| |||
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
115 | 119 | | |
116 | 120 | | |
117 | 121 | | |
| |||
120 | 124 | | |
121 | 125 | | |
122 | 126 | | |
123 | | - | |
| 127 | + | |
124 | 128 | | |
125 | 129 | | |
126 | 130 | | |
| |||
196 | 200 | | |
197 | 201 | | |
198 | 202 | | |
| 203 | + | |
| 204 | + | |
199 | 205 | | |
200 | | - | |
201 | | - | |
| 206 | + | |
| 207 | + | |
202 | 208 | | |
203 | 209 | | |
204 | | - | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
205 | 214 | | |
206 | 215 | | |
207 | 216 | | |
208 | 217 | | |
209 | 218 | | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
| 219 | + | |
218 | 220 | | |
219 | 221 | | |
220 | 222 | | |
| |||
Lines changed: 11 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
176 | 176 | | |
177 | 177 | | |
178 | 178 | | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
179 | 188 | | |
180 | 189 | | |
181 | 190 | | |
| |||
1980 | 1989 | | |
1981 | 1990 | | |
1982 | 1991 | | |
| 1992 | + | |
| 1993 | + | |
1983 | 1994 | | |
1984 | 1995 | | |
1985 | 1996 | | |
| |||
Lines changed: 14 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
| 65 | + | |
| 66 | + | |
65 | 67 | | |
66 | 68 | | |
67 | 69 | | |
| |||
85 | 87 | | |
86 | 88 | | |
87 | 89 | | |
| 90 | + | |
88 | 91 | | |
89 | 92 | | |
90 | 93 | | |
| |||
176 | 179 | | |
177 | 180 | | |
178 | 181 | | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
179 | 186 | | |
180 | 187 | | |
181 | 188 | | |
| |||
195 | 202 | | |
196 | 203 | | |
197 | 204 | | |
| 205 | + | |
198 | 206 | | |
199 | 207 | | |
200 | 208 | | |
| |||
209 | 217 | | |
210 | 218 | | |
211 | 219 | | |
| 220 | + | |
212 | 221 | | |
213 | 222 | | |
214 | 223 | | |
| |||
269 | 278 | | |
270 | 279 | | |
271 | 280 | | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
272 | 286 | | |
273 | 287 | | |
Lines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
94 | 94 | | |
95 | 95 | | |
96 | 96 | | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
97 | 101 | | |
98 | 102 | | |
99 | 103 | | |
| |||
Lines changed: 239 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
0 commit comments