# eea/eionet.datadict architecture

> Architecture diagram of the GitHub repository eea/eionet.datadict, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-05-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/eea/eionet.datadict
- Repository: https://github.com/eea/eionet.datadict

## Overview

1. **What this system is**
   - This is a single Java web application packaged as a WAR and deployed on Tomcat.
   - It implements the EIONET Data Dictionary, a metadata registry for datasets, tables, data elements, namespaces, vocabularies, and schema sets.
   - Runtime persistence is centered on MariaDB/MySQL; startup initializes schema via database migration/bootstrapping.

2. **Top-level architecture**
   - The app is layered: web presentation, application/service logic, persistence/DAO, and shared domain/utilities.
   - There are two major code families:
     - `eionet.datadict` — newer modular services, DAOs, async infrastructure, security, and web controllers.
     - `eionet.meta` — a larger legacy subsystem with servlet/action-bean style endpoints, exporters, importers, and older DAO/service APIs.
   - These coexist in the same WAR and share the same database and supporting configuration.

3. **Web/UI boundary**
   - User-facing pages are mostly JSP-based, with Stripes-style ActionBeans under `eionet.web.action` and older servlets under `eionet.meta`.
   - The web layer includes filters, exception handlers, content negotiation, and page helpers.
   - Presentation artifacts live under `src/main/webapp` and include JSPs, JSTL/tag files, static JS/CSS, and FreeMarker templates for some notifications.

4. **Business/service layer**
   - The service layer is where most business rules live: dataset/table/element management, vocabulary handling, authentication, ACL checks, caching, cleanup, and checkout/check-in workflows.
   - In the newer stack, services such as `DataSetService`, `DataSetTableService`, `AttributeService`, `LdapService`, `JWTService`, `AclService`, and `CacheService` orchestrate DAOs and apply validation.
   - The legacy `eionet.meta.service` package provides parallel capabilities for schema, vocabulary import/export, site codes, RDF conversion, and reference matching.

5. **Persistence and database access**
   - Data access is concentrated in DAO layers:
     - `eionet.datadict.dal` / `...dal.impl` for the newer stack.
     - `eionet.meta.dao.mysql` and related interfaces for the legacy stack.
   - DAOs use JDBC templates and custom SQL utilities rather than a full ORM.
   - Domain objects model metadata concepts such as `DataSet`, `DatasetTable`, `DataElement`, `Attribute`, `FixedValue`, `Vocabulary`, `SchemaSet`, `Namespace`, and async task history.

6. **Core domain boundaries**
   - The system’s main entities are:
     - datasets and tables,
     - data elements and attributes,
     - fixed values / vocabularies / concept lists,
     - namespaces and RDF namespaces,
     - schema sets and schemas,
     - site codes and access rules,
     - async task execution records.
   - Many features are centered on editing, searching, and exporting these metadata objects, not on transactional business data.

7. **Import, export, and transformation pipelines**
   - A major architectural concern is converting DD metadata into many delivery formats:
     - RDF, XML instance/schema, JSON, XLS/ODS, PDF, DBF, MDB/MS Access, and code lists.
   - Imports handle CSV, RDF, and uploaded archives; decompression and file-bean handling are separated into I/O helper services.
   - Exports are organized by format-specific modules under `eionet.meta.exports.*`, each reading the domain model and rendering a target representation.
   - Static templates and seed files under `sql/`, `opendoc/`, and `msaccess/` support these generation pipelines.

8. **Asynchronous jobs and scheduling**
   - Background work is handled by Quartz-based scheduling plus an async task framework in `eionet.datadict.infrastructure.asynctasks`.
   - Tasks cover things like vocabulary import/check-in/check-out, reference matching, and scheduled sync/maintenance.
   - Execution history is persisted, and aspects are used to capture task history automatically.
   - This subsystem is a key boundary between synchronous UI actions and long-running metadata operations.

9. **Security and access control**
   - Access is controlled by a combination of ACL files, CAS-based login, LDAP integration, and JWT support for API-style access.
   - ACL configuration is file-based in the repository and supplemented by database-backed permission logic.
   - The app has explicit security filters and web security config, plus services for generating/verifying JWT tokens and resolving user/group information.

10. **External integrations and infrastructure dependencies**
   - Primary external systems are the relational database, LDAP, CAS, and any downstream notification/event endpoints used by legacy modules.
   - The app also depends on file-system storage for documentation/uploads and on Jena-style RDF utilities for semantic exports/imports.
   - Deployment is environment-driven via properties files, Tomcat context configuration, and Docker/Jenkins support.

11. **Repository structure as an architecture map**
   - `src/main/java` holds the runtime application code.
   - `src/main/resources` contains runtime configuration, logging, Quartz, Spring, ACL, and export settings.
   - `src/main/webapp` contains the UI, templates, static assets, and deployment descriptors.
   - `sql/`, `doc/`, `msaccess/`, and `opendoc/` hold schema seed data, help content, and format templates that directly feed application behavior.

12. **How requests typically flow**
   - A browser or API client enters through Tomcat filters and web security.
   - The request is handled by a JSP/ActionBean/Servlet controller.
   - Controller code delegates to a service, which enforces rules and coordinates related DAOs.
   - DAOs read/write MariaDB/MySQL.
   - The response is either a rendered page, a download/export file, or an async task submission whose result is later polled.

Main entry points: [`src/main/resources/datadict.properties`](https://github.com/eea/eionet.datadict/blob/master/src/main/resources/datadict.properties) (Config Assets), [`src/main/java/eionet/web/filter/ContentNegotiationFilter.java`](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/web/filter/ContentNegotiationFilter.java) (Web Filters), [`src/main/java/eionet/datadict/services/DataSetService.java`](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/datadict/services/DataSetService.java) (DD Services), [`src/main/java/eionet/meta/service/VocabularyServiceImpl.java`](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/service/VocabularyServiceImpl.java) (Legacy Services)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web UI"]
  node_web_filters["Web Filters<br/>HTTP boundary"]
  node_new_controllers["DD Controllers<br/>Stripes/Spring web"]
  node_legacy_servlets["Legacy Servlets<br/>Servlet endpoints"]
  node_jsp_views["JSP Views<br/>Presentation<br/>[index.jsp]"]
end

subgraph group_newstack["New Stack"]
  node_new_services["DD Services<br/>Service layer"]
  node_new_data[("DD Data Access<br/>DAO layer<br/>[DatasetDao.java]")]
  node_async_runtime["Async Runtime<br/>Async jobs"]
  node_new_domain["DD Domain<br/>Metadata model<br/>[DataSet.java]"]
end

subgraph group_legacy["Legacy Meta"]
  node_legacy_services["Legacy Services<br/>Business services"]
  node_legacy_daos[("Legacy DAOs<br/>MySQL DAO")]
  node_legacy_exports["Export Pipelines<br/>Format renderers<br/>[RdfServlet.java]"]
  node_legacy_imports["Import Pipelines<br/>Import handlers"]
  node_legacy_domain["Legacy Domain<br/>Metadata model<br/>[DataSet.java]"]
end

subgraph group_infra["Runtime Infra"]
  node_war["WAR App<br/>Tomcat WAR<br/>[pom.xml]"]
  node_security["Security<br/>AuthN/AuthZ"]
  node_db[("MariaDB/MySQL<br/>Relational DB<br/>[dd-struct.xml]")]
end

subgraph group_assets["Repo Assets"]
  node_config_assets["Config Assets<br/>Repo config"]
end

node_war -->|"hosts"| node_web_filters
node_web_filters -->|"enforces"| node_security
node_web_filters -->|"routes"| node_new_controllers
node_web_filters -->|"routes"| node_legacy_servlets
node_new_controllers -->|"delegates to"| node_new_services
node_new_controllers -->|"renders"| node_jsp_views
node_legacy_servlets -->|"delegates to"| node_legacy_services
node_legacy_servlets -->|"streams"| node_legacy_exports
node_legacy_services -->|"uses"| node_legacy_daos
node_legacy_services -->|"models"| node_legacy_domain
node_new_services -->|"uses"| node_new_data
node_new_services -->|"models"| node_new_domain
node_new_data -->|"reads/writes"| node_db
node_legacy_daos -->|"reads/writes"| node_db
node_new_services -->|"submits jobs"| node_async_runtime
node_async_runtime -->|"records"| node_db
node_legacy_imports -->|"feeds"| node_legacy_services
node_legacy_exports -->|"renders"| node_legacy_domain
node_config_assets -->|"configures"| node_security
node_config_assets -->|"bootstraps"| node_db
node_config_assets -->|"templates"| node_legacy_exports
node_config_assets -->|"supplies"| node_jsp_views

click node_war "https://github.com/eea/eionet.datadict/blob/master/pom.xml"
click node_web_filters "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/web/filter/ContentNegotiationFilter.java"
click node_new_controllers "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/web/action/IndexPageActionBean.java"
click node_legacy_servlets "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/DatasetsServlet.java"
click node_jsp_views "https://github.com/eea/eionet.datadict/blob/master/src/main/webapp/pages/index.jsp"
click node_new_services "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/datadict/services/DataSetService.java"
click node_new_data "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/datadict/dal/DatasetDao.java"
click node_async_runtime "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/datadict/infrastructure/asynctasks/AsyncTaskManager.java"
click node_new_domain "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/datadict/model/DataSet.java"
click node_legacy_services "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/service/VocabularyServiceImpl.java"
click node_legacy_daos "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/dao/mysql/DataSetDAOImpl.java"
click node_legacy_exports "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/exports/rdf/RdfServlet.java"
click node_legacy_imports "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/imp/VocabularyCSVImportHandler.java"
click node_legacy_domain "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/dao/domain/DataSet.java"
click node_security "https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/datadict/security/WebSecurityConfig.java"
click node_db "https://github.com/eea/eionet.datadict/blob/master/sql/dd-struct.xml"
click node_config_assets "https://github.com/eea/eionet.datadict/blob/master/src/main/resources/datadict.properties"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_web_filters,node_new_controllers,node_legacy_servlets,node_jsp_views toneBlue
class node_new_services,node_new_data,node_async_runtime,node_new_domain toneAmber
class node_legacy_services,node_legacy_daos,node_legacy_exports,node_legacy_imports,node_legacy_domain toneMint
class node_war,node_security,node_db toneRose
class node_config_assets toneIndigo
```

## Components

### Web UI

Browser/API entry points, controllers, filters, and rendered views.

- [Web Filters](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/web/filter/ContentNegotiationFilter.java): HTTP boundary · Request filters and exception handling before controllers execute. · `src/main/java/eionet/web/filter/ContentNegotiationFilter.java`
- [DD Controllers](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/web/action/IndexPageActionBean.java): Stripes/Spring web · Newer web controllers and API endpoints for datasets, tables, vocabularies, schemas, and async tasks. · `src/main/java/eionet/web/action/IndexPageActionBean.java`
- [Legacy Servlets](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/DatasetsServlet.java): Servlet endpoints · Older servlet-based entry points still serving login, search, downloads, import, and document flows. · `src/main/java/eionet/meta/DatasetsServlet.java`
- [JSP Views](https://github.com/eea/eionet.datadict/blob/master/src/main/webapp/pages/index.jsp): Presentation · JSP pages, tags, and client assets used to render the UI. · `src/main/webapp/pages/index.jsp`

### New Stack

Modular services, DAOs, async infrastructure, and web controllers under eionet.datadict.

- [DD Services](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/datadict/services/DataSetService.java): Service layer · Core business services for datasets, tables, attributes, ACL, LDAP, JWT, cache, cleanup, and checkouts. · `src/main/java/eionet/datadict/services/DataSetService.java`
- [DD Data Access](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/datadict/dal/DatasetDao.java): DAO layer · JDBC-based DAOs for datasets, tables, elements, vocabularies, namespaces, cache, and async task history. · `src/main/java/eionet/datadict/dal/DatasetDao.java`
- [Async Runtime](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/datadict/infrastructure/asynctasks/AsyncTaskManager.java): Async jobs · Task builder/manager, Quartz scheduling, and background vocabulary operations with persisted execution history. · `src/main/java/eionet/datadict/infrastructure/asynctasks/AsyncTaskManager.java`
- [DD Domain](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/datadict/model/DataSet.java): Metadata model · Core metadata entities such as datasets, tables, data elements, attributes, vocabularies, namespaces, and task records. · `src/main/java/eionet/datadict/model/DataSet.java`

### Legacy Meta

Older servlet/action-bean, service, export, import, and DAO subsystem under eionet.meta.

- [Legacy Services](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/service/VocabularyServiceImpl.java): Business services · Parallel legacy services for schema, vocabulary, site codes, RDF conversion, and reference matching. · `src/main/java/eionet/meta/service/VocabularyServiceImpl.java`
- [Legacy DAOs](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/dao/mysql/DataSetDAOImpl.java): MySQL DAO · Legacy MySQL-backed DAOs and query utilities for datasets, schemas, vocabularies, site codes, and folders. · `src/main/java/eionet/meta/dao/mysql/DataSetDAOImpl.java`
- [Export Pipelines](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/exports/rdf/RdfServlet.java): Format renderers · Format-specific export modules for RDF, XML, JSON, XLS/ODS, PDF, DBF, MDB, schema, and codelist outputs. · `src/main/java/eionet/meta/exports/rdf/RdfServlet.java`
- [Import Pipelines](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/imp/VocabularyCSVImportHandler.java): Import handlers · CSV/RDF/archive import handlers and save workflows for datasets and vocabularies. · `src/main/java/eionet/meta/imp/VocabularyCSVImportHandler.java`
- [Legacy Domain](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/meta/dao/domain/DataSet.java): Metadata model · Legacy domain objects for datasets, tables, elements, schema sets, vocabularies, folders, and site codes. · `src/main/java/eionet/meta/dao/domain/DataSet.java`

### Runtime Infra

Database bootstrap, scheduling, security, and external integration boundaries.

- [WAR App](https://github.com/eea/eionet.datadict/blob/master/pom.xml): Tomcat WAR · Single deployed Java web application containing both new and legacy code families. · `pom.xml`
- [Security](https://github.com/eea/eionet.datadict/blob/master/src/main/java/eionet/datadict/security/WebSecurityConfig.java): AuthN/AuthZ · CAS, LDAP, JWT, ACL, and request filtering for user and API access. · `src/main/java/eionet/datadict/security/WebSecurityConfig.java`
- [MariaDB/MySQL](https://github.com/eea/eionet.datadict/blob/master/sql/dd-struct.xml): Relational DB · Primary persistent store initialized and maintained by SQL seed/migration scripts. · `sql/dd-struct.xml`

### Repo Assets

SQL seed data, ACLs, templates, and deployment/configuration files that shape runtime behavior.

- [Config Assets](https://github.com/eea/eionet.datadict/blob/master/src/main/resources/datadict.properties): Repo config · Properties, ACL files, templates, seed SQL, and deployment descriptors that drive startup and exports. · `src/main/resources/datadict.properties`

## Connections

- WAR App → Web Filters: hosts · Tomcat deploys the application and activates request filtering.
- Web Filters → Security: enforces · Security and content negotiation are applied before controller dispatch.
- Web Filters → DD Controllers: routes · Filtered requests reach newer ActionBean/controller endpoints.
- Web Filters → Legacy Servlets: routes · Filtered requests also reach older servlet endpoints.
- DD Controllers → DD Services: delegates to · Controllers orchestrate business logic through service interfaces.
- DD Controllers → JSP Views: renders · UI actions return JSP pages, fragments, and downloads.
- Legacy Servlets → Legacy Services: delegates to · Legacy endpoints call the older service layer.
- Legacy Servlets → Export Pipelines: streams · Several servlets produce export/download responses.
- Legacy Services → Legacy DAOs: uses · Legacy services coordinate persistence through MySQL DAOs.
- Legacy Services → Legacy Domain: models · Services operate on legacy metadata domain objects.
- DD Services → DD Data Access: uses · New services coordinate through DAO abstractions.
- DD Services → DD Domain: models · Services operate on the newer metadata entities.
- DD Data Access → MariaDB/MySQL: reads/writes · JDBC DAOs persist metadata and task state to MariaDB/MySQL.
- Legacy DAOs → MariaDB/MySQL: reads/writes · Legacy DAOs use the same relational database.
- DD Services → Async Runtime: submits jobs · Long-running vocabulary and maintenance work is offloaded to async tasks.
- Async Runtime → MariaDB/MySQL: records · Async execution history and scheduler state are persisted.
- Import Pipelines → Legacy Services: feeds · Import handlers populate the legacy service layer with parsed metadata.
- Export Pipelines → Legacy Domain: renders · Export modules read the legacy domain model to generate output formats.
- Config Assets → Security: configures · ACL and auth settings drive security behavior.
- Config Assets → MariaDB/MySQL: bootstraps · SQL seed and structure files initialize the database schema and data.
- Config Assets → Export Pipelines: templates · Template and seed assets support legacy export generation.
- Config Assets → JSP Views: supplies · Web resources, JSP fragments, tags, and static assets support presentation.
