Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
599a1f8
claude init
iTerminate Jun 26, 2026
90c2355
Move IOC instructions into the top level of the ioc details page.
iTerminate Jun 29, 2026
89c5d3a
Make it easier to read the ioc instructions with a white background.
iTerminate Jun 29, 2026
9cf4cf0
The expand button should go straight to editing when the user is logg…
iTerminate Jun 29, 2026
45bcb3d
Add Search Settings for searching IOCs
iTerminate Jun 29, 2026
111e682
only search iocs for this domain. This can be further enhanced by sea…
iTerminate Jun 29, 2026
ab099f2
Expose the ioc search results.
iTerminate Jun 29, 2026
6e7b721
Add ioc and application search results to the REST API.
iTerminate Jun 29, 2026
65deb69
Resolve the index for the new settings.
iTerminate Jun 30, 2026
5c111fb
Add a claude note to resolve the index for the new settings.
iTerminate Jun 30, 2026
0634944
Add stored procedure for searching ioc items on db layer.
iTerminate Jun 30, 2026
b1ba523
Use the new search stored procedure.
iTerminate Jun 30, 2026
cb2cdf4
Unused import
iTerminate Jun 30, 2026
acc05c2
undo the unimplemented code
iTerminate Jun 30, 2026
e7803e0
Update the database to provide search for property values including t…
iTerminate Jun 30, 2026
a0c3f4b
Integrate with database.
iTerminate Jun 30, 2026
e2f1f2f
Integrate with database.
iTerminate Jun 30, 2026
9d6a060
Add search UI. Including redirect for items.
iTerminate Jun 30, 2026
185195b
Will use query builder for more advanced search where order doesn't m…
iTerminate Jun 30, 2026
78d65d0
Add a query builder for searching property text/values where order do…
iTerminate Jun 30, 2026
792469b
Shorten the match descirpitons for the text filed matches on the sear…
iTerminate Jun 30, 2026
952c9b7
Support shortened match string with multiple word text searches in a …
iTerminate Jun 30, 2026
88396fc
Add a copy permalink button for property values.
iTerminate Jun 30, 2026
0388662
Add a dialog for displaying property value from permalink.
iTerminate Jun 30, 2026
f951f39
Do not drop the propertyValueId in the URL so it can get passed to pr…
iTerminate Jun 30, 2026
0773079
Fix reference issue for copy to clipboard.
iTerminate Jun 30, 2026
197dad8
Add functionality to open the appropriate dialog on page load.
iTerminate Jun 30, 2026
03dfb7a
Use the objectValue to display images links, etc correctly.
iTerminate Jun 30, 2026
9302e6e
Implement a short URL for property value permalink.
iTerminate Jun 30, 2026
adb0762
Clean up the redirect to item function and use the new redirect perma…
iTerminate Jul 1, 2026
4da61e6
Update to log4j 2.26.0
iTerminate Jul 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Environment bootstrap

Every shell that builds, deploys, or runs CDB **must first source `setup.sh`** from the repo root. It sets `CDB_ROOT_DIR`, `CDB_INSTALL_DIR`, `CDB_DATA_DIR`, `CDB_VAR_DIR`, `CDB_SUPPORT_DIR`, `CDB_GLASSFISH_DIR`, `CDB_PYTHON_DIR`, `PYTHONPATH`, and prepends `bin/`, Ant, Java, Payara, NetBeans-bundled Maven, the support Python, and MariaDB to `PATH`. Most `make` targets and `sbin/` scripts assume those variables exist; running them without sourcing first will fail in non-obvious ways.

The layout is intentionally **out-of-tree**: `CDB_ROOT_DIR` is the source checkout, but the dependency tree lives at `$CDB_INSTALL_DIR/support-<hostname>/` (Payara, Java, Ant, NetBeans, MariaDB, Python) created by `make support`. The deployed app, data, logs, and config live under `$CDB_INSTALL_DIR/{etc,var,data,backup}`. Do not commit or read anything from `support-*/` — it is host-specific.

## Common commands

All `make` targets must be run from the repo root after `source setup.sh`.

```sh
# First-time / dev environment setup
make support # downloads & builds Payara, Java, Python, etc. into support-<hostname>/
make support-mysql # optional bundled MariaDB
make support-netbeans # optional NetBeans IDE bundle
make dev-config # interactive: writes LDAP/email config & per-host build properties

# Database (production "cdb" vs dev "cdb_dev" — every db/deploy target has a -dev twin)
make clean-db # drop & recreate cdb with seed data from db/sql/clean
make test-db # recreate cdb with fixtures from db/sql/test
make db # recreate cdb without populating (schema only)
make backup # dumps cdb to $CDB_INSTALL_DIR/backup/cdb/<YYYYMMDD>/
make clean-db-dev # same, against cdb_dev

# Build & deploy the Java web portal (WAR -> Payara)
make configure-web-portal # one-time: writes glassfish-resources.xml, etc.
make deploy-web-portal # builds dist/CdbWebPortal.war via Ant and deploys to Payara
make undeploy-web-portal
make deploy-web-portal-dev # deploys to dev domain, uses cdb_dev

# Plugins
make deploy-cdb-plugin # interactive picker; see tools/developer_tools/cdb_plugins/plugins/

# Full test suite (interactive — prompts for DB root password)
make test # runs ./sbin/cdb_test.sh: backs up cdb, swaps in test DB,
# runs Maven unit tests + pytest API tests + Selenium GUI tests,
# then restores the backup
```

### Test targets in isolation

```sh
# Java unit tests (Arquillian + embedded Glassfish)
cd tools/developer_tools/code_testing/CdbWebPortalTest && mvn test
mvn test -Dtest=ClassName#methodName # single test

# Python API tests — require the portal to be running on localhost:8080
cd tools/developer_tools/python-client && ./generatePyClient.sh http://localhost:8080/cdb
cd tools/developer_tools/python-client/test && pytest api_test.py
pytest api_test.py::TestClass::test_method # single test

# Selenium GUI tests
cd tools/developer_tools/portal_testing/PythonSeleniumTest && pytest gui_test.py
```

### Server / log management

```sh
./etc/init.d/cdb-glassfish restart
./etc/init.d/cdb-mysqld start # only if using bundled MariaDB
tail -f $CDB_SUPPORT_DIR/payara/$CDB_HOST_ARCH/glassfish/domains/production/logs/server.log
```

## High-level architecture

ComponentDB has **three deployable pieces** plus a generated client. They communicate through the database and through the portal's REST API.

### 1. Java web portal — `src/java/CdbWebPortal/`

A JSF (PrimeFaces) + JAX-RS application packaged as a WAR and deployed to **Payara 5**. Built with **Ant via the NetBeans project** (`build.xml` → `nbproject/build-impl.xml`); the `make` target invokes `cdb-ant` from the support dir. Maven `pom-wip-jdk11.xml` exists but is not the build of record.

Source root: `src/java/CdbWebPortal/src/java/gov/anl/aps/cdb/` with these top-level packages:

- `portal/` — the JSF webapp.
- `model/db/entities/` — JPA entities (EclipseLink). Item hierarchy is the core domain model: `Item` is the abstract parent; `ItemDomain*` subclasses (`ItemDomainCatalog`, `ItemDomainInventory`, `ItemDomainLocation`, `ItemDomainMachineDesign`, `ItemDomainCableCatalog`, `ItemDomainCableDesign`, `ItemDomainCableInventory`, `ItemDomainApp`, `ItemDomainMAARC`, `ItemDomainAppDeployment`) implement domain-specific behavior. Catalog/Inventory base classes are shared.
- `model/db/beans/` — `@Stateless` EJB facades wrapping JPA queries.
- `controllers/` — `@SessionScoped`/`@ViewScoped` JSF managed beans. Naming mirrors the entity: e.g. `ItemDomainCatalogController` ↔ `ItemDomainCatalog`. `CdbDomainEntityController` is the common base. `controllers/extensions/` adds cross-cutting helpers, `controllers/settings/` persists user UI prefs.
- `import_export/` — wizard-driven spreadsheet (XLSX) import/export framework; `import_/objects/specs/` defines per-domain column specs and `handlers/` define value coercion.
- `view/` — JSF beans and value objects backing views.
- `plugins/` — `CdbPluginManager` discovers plugin JARs deployed under `support/`; see `tools/developer_tools/cdb_plugins/` for the plugin install tooling.
- `rest/` — JAX-RS endpoints exposed at `/cdb/api`. One `*Route` class per resource (`ItemRoute`, `MachineDesignItemRoute`, `CableDesignItemRoute`, `UsersRoute`, `AuthenticationRoute`, etc.) under `rest/routes/`. `rest/entities/` are the request/response DTOs; `rest/authentication/` issues JWTs; `rest/provider/` registers JAX-RS providers. The OpenAPI surface is declared in `src/java/openapi.yaml` and drives Python client generation — keep it in sync when adding/changing routes.
- `common/` — shared exceptions, constants, value objects used by both `portal/` and `rest/`.
- `api/`, `connectors/` — internal API surfaces and external system connectors.

**JSF views, templates, and static assets** live in `web/` (`web/views/`, `web/templates/`, `web/resources/`, `web/WEB-INF/`). `web/WEB-INF/glassfish-web.xml` and `src/java/cdb.portal.properties` are generated from `.template` files by `make dev-config` / `make configure-web-portal` — never edit the generated files; edit the templates.

### 2. Python CDB web service — `src/python/cdb/`

A CherryPy service that runs on port 10232 (`./sbin/cdbWebService.sh`), handling email notifications, async tasks, and a legacy SOAP/REST surface. Marked **deprecated** but still part of the distribution for legacy integrations. Layout follows the `common/` + `cdb_web_service/` split with `api/`, `cli/`, `impl/`, `service/`, `tasks/`, `plugins/`, `java_api/` (Python wrappers around the Java REST API). New features should go in the Java REST layer instead.

### 3. Python client + CLI — `tools/developer_tools/python-client/`

- `cdbApi/` is **generated** from `openapi.yaml` by `./generatePyClient.sh <portal-url>` (uses openapi-generator). Do not hand-edit it — regenerate after changing the Java REST routes. `setup-api.py` packages it as `ComponentDB_API` for PyPI.
- `CdbApiFactory.py` is the hand-written entry point that hides authentication & client wiring.
- `cdbCli/` is the user-facing CLI (`cdbSearch`, `cdbInfo`, `cdb-cli`); see `docs/CLI.md` for usage and option reference. `cli-template/` holds skeletons for new commands.

### Database — `db/sql/`

MariaDB 10.5. Authoritative schema is the set of `create_cdb_tables.sql`, `create_stored_procedures.sql`, `create_triggers.sql`, `create_views.sql` in `db/sql/`, applied by `sbin/cdb_create_db.sh`. Initial reference data lives in `db/sql/clean/populate_*.sql` (used by `make clean-db`). Test fixtures in `db/sql/test/`.

**Releases bump the version in `etc/version` and add `db/sql/updates/updateTo<NEW_VERSION>.sql`** containing the idempotent (INSERT IGNORE / ALTER ... IF NOT EXISTS) migrations needed to bring an existing prod DB to the new schema. Header comments in each update file document how to run it. The existing version chain (e.g. `updateTo3.15.5.sql` → `updateTo3.17.0.sql`) is the template; do not retroactively edit older update scripts.

**Adding a setting:** `setting_type` ids are organized into per-type blocks with numeric gaps between blocks (e.g. `15xxx` Search, `16xxx` Source, `22xxx` MAARC) so each type has room for new entries. A new setting takes the next free id at the end of its type block — never reuse an id or insert one mid-block (the gap before the next block is the room reserved for this). Add the identical row to all seed copies (`db/sql/{clean,test,static}/populate_setting_type.sql`) and to the current release's `db/sql/updates/updateTo<VERSION>.sql`.

## Repo-specific conventions

- **Generated files that look like sources** are common: `cdb.portal.properties`, `web/WEB-INF/glassfish-web.xml`, `web/WEB-INF/web.xml`, `setup/glassfish-resources.xml`, `nbproject/private/private.properties`, and everything under `tools/developer_tools/python-client/cdbApi/`. They are produced from `*.template` files (or via openapi-generator) by `dev-config` / `configure-web-portal` / `dist` targets and are in `.gitignore`. Edit the template, regenerate, then commit only the template.
- **`cdb` vs `cdb_dev`**: every db, deploy, undeploy, and backup target has a `-dev` variant that targets a separate database name and Payara domain, so a developer can run both side-by-side. When adding new admin scripts, follow the same pattern (first arg is DB name, defaulting to `cdb`).
- **Single canonical version string**: update `etc/version`, `src/java/CdbWebPortal/src/java/openapi.yaml` (`info.version`), `tools/developer_tools/python-client/setup-api.py`, and `tools/developer_tools/python-client/setup-cli.py` together. Past release commits (`git log --grep "Prepare relase"`) show the full set of files that need bumping.
- **Plugins** under `tools/developer_tools/cdb_plugins/plugins/<name>/` extend both the Java portal (deployed via `make deploy-cdb-plugin` → `update_plugin_generated_files.py`) and the Python web service. `pluginTemplates/` is the scaffold.
- **REST changes touch three places**: the Java route, `openapi.yaml`, and (after `generatePyClient.sh`) the regenerated `cdbApi/` package. The Python API tests in `tools/developer_tools/python-client/test/api_test.py` are the integration check.

## Reference docs

- `README.md` — full deployment and upgrade walk-through (commands here are abbreviated).
- `docs/CLI.md` — `cdbSearch` / `cdbInfo` / `cdb-cli` reference.
- `docs/release-notes/<version>.md` — per-release notes; mirror this format for new releases.
- `docs/db/CdbSchema-v3.0-3.pdf` — ER diagram (somewhat dated but useful for the Item hierarchy).
- External developer guide: <https://confluence.aps.anl.gov/display/APSUCMS/Developer+Guide> (referenced from README).
3 changes: 3 additions & 0 deletions db/sql/clean/populate_setting_type.sql
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ INSERT INTO `setting_type` VALUES
(15011,'Search.Display.Users','Display search result for users.','false'),
(15012,'Search.Display.UserGroups','Display search result for user groups.','false'),
(15013,'Search.DisplayItemDomainMachineDesign','Display search result for machine design items','true'),
(15018,'Search.Display.ItemDomainMachineDesignIOC','Display search result for IOC items.','true'),
(15019,'Search.Display.ItemDomainApp','Display search result for application items.','true'),
(15020,'Search.Display.PropertyValue','Display search result for property values.','true'),
(16000,'Source.List.Display.ContactInfo','Display source contact info.','true'),
(16001,'Source.List.Display.Description','Display source description.','true'),
(16002,'Source.List.Display.Url','Display source URL.','true'),
Expand Down
28 changes: 28 additions & 0 deletions db/sql/create_stored_procedures.sql
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,34 @@ BEGIN
LIMIT limit_row;
END //

DROP PROCEDURE IF EXISTS search_ioc_items;//
CREATE PROCEDURE `search_ioc_items` (IN limit_row int, IN search_string VARCHAR(255))
BEGIN
DECLARE ioc_entity_type_id INT;
SET ioc_entity_type_id = 11; -- EntityTypeName.IOC_ID

SET search_string = CONCAT('%', search_string, '%');
SELECT DISTINCT item.* from item
INNER JOIN v_item_self_element ise ON item.id = ise.item_id
INNER JOIN item_element ie ON ise.self_element_id = ie.id
INNER JOIN entity_info ei ON ise.entity_info_id = ei.id
INNER JOIN user_info owneru ON ei.owner_user_id = owneru.id
INNER JOIN user_info creatoru ON ei.created_by_user_id = creatoru.id
INNER JOIN user_info updateu ON ei.last_modified_by_user_id = updateu.id
INNER JOIN item_entity_type iet ON iet.item_id = item.id AND iet.entity_type_id = ioc_entity_type_id
WHERE (
item.name LIKE search_string
OR item.qr_id LIKE search_string
OR item.item_identifier1 LIKE search_string
OR item.item_identifier2 LIKE search_string
OR ie.description LIKE search_string
OR owneru.username LIKE search_string
OR creatoru.username LIKE search_string
OR updateu.username LIKE search_string
)
LIMIT limit_row;
END //

DROP PROCEDURE IF EXISTS search_item_elements;//
CREATE PROCEDURE `search_item_elements` (IN limit_row int, IN search_string VARCHAR(255))
BEGIN
Expand Down
5 changes: 4 additions & 1 deletion db/sql/static/populate_setting_type.sql
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,10 @@ description.','true'),
(15014,'Search.Display.ItemDomainCableCatalog','Display search result for cable catalog items.','true'),
(15015,'Search.Display.ItemDomainCableInventory','Display search result for cable inventory items.','true'),
(15016,'Search.Display.ItemDomainCableDesign','Display search result for cable design items.','true'),
(15017,'Search.Display.ItemDomainMAARC', 'Display search result for MAARC items', 'false'),
(15017,'Search.Display.ItemDomainMAARC', 'Display search result for MAARC items', 'false'),
(15018,'Search.Display.ItemDomainMachineDesignIOC','Display search result for IOC items.','true'),
(15019,'Search.Display.ItemDomainApp','Display search result for application items.','true'),
(15020,'Search.Display.PropertyValue','Display search result for property values.','true'),
(16000,'Source.List.Display.ContactInfo','Display source contact info.','true'),
(16001,'Source.List.Display.Description','Display source description.','true'),
(16002,'Source.List.Display.Url','Display source URL.','true'),
Expand Down
3 changes: 3 additions & 0 deletions db/sql/test/populate_setting_type.sql
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,9 @@ INSERT INTO `setting_type` VALUES
(15015,'Search.Display.ItemDomainCableInventory','Display search result for cable inventory items.','true'),
(15016,'Search.Display.ItemDomainCableDesign','Display search result for cable design items.','true'),
(15017,'Search.Display.ItemDomainMAARC','Display search result for MAARC items','false'),
(15018,'Search.Display.ItemDomainMachineDesignIOC','Display search result for IOC items.','true'),
(15019,'Search.Display.ItemDomainApp','Display search result for application items.','true'),
(15020,'Search.Display.PropertyValue','Display search result for property values.','true'),
(16000,'Source.List.Display.ContactInfo','Display source contact info.','true'),
(16001,'Source.List.Display.Description','Display source description.','true'),
(16002,'Source.List.Display.Url','Display source URL.','true'),
Expand Down
46 changes: 46 additions & 0 deletions db/sql/updates/updateTo3.18.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
--
-- Copyright (c) UChicago Argonne, LLC. All rights reserved.
-- See LICENSE file.
--

-- Execute by running `mysql CDB_DB_NAME -h 127.0.0.1 -u cdb -p < updateTo3.16.2.sql`

INSERT IGNORE INTO `setting_type` VALUES
(15018,'Search.Display.ItemDomainMachineDesignIOC','Display search result for IOC items.','true'),
(15019,'Search.Display.ItemDomainApp','Display search result for application items.','true'),
(15020,'Search.Display.PropertyValue','Display search result for property values.','true');

-- Add text property value (value/text/tag) matching to the item search procedures
-- and a dedicated IOC item search procedure (used to search markdown IOC instructions).

delimiter //

DROP PROCEDURE IF EXISTS search_ioc_items;//
CREATE PROCEDURE `search_ioc_items` (IN limit_row int, IN search_string VARCHAR(255))
BEGIN
DECLARE ioc_entity_type_id INT;
SET ioc_entity_type_id = 11; -- EntityTypeName.IOC_ID

SET search_string = CONCAT('%', search_string, '%');
SELECT DISTINCT item.* from item
INNER JOIN v_item_self_element ise ON item.id = ise.item_id
INNER JOIN item_element ie ON ise.self_element_id = ie.id
INNER JOIN entity_info ei ON ise.entity_info_id = ei.id
INNER JOIN user_info owneru ON ei.owner_user_id = owneru.id
INNER JOIN user_info creatoru ON ei.created_by_user_id = creatoru.id
INNER JOIN user_info updateu ON ei.last_modified_by_user_id = updateu.id
INNER JOIN item_entity_type iet ON iet.item_id = item.id AND iet.entity_type_id = ioc_entity_type_id
WHERE (
item.name LIKE search_string
OR item.qr_id LIKE search_string
OR item.item_identifier1 LIKE search_string
OR item.item_identifier2 LIKE search_string
OR ie.description LIKE search_string
OR owneru.username LIKE search_string
OR creatoru.username LIKE search_string
OR updateu.username LIKE search_string
)
LIMIT limit_row;
END //

delimiter ;
Binary file removed src/java/CdbWebPortal/lib/log4j-api-2.17.0.jar
Binary file not shown.
Binary file added src/java/CdbWebPortal/lib/log4j-api-2.26.0.jar
Binary file not shown.
Binary file removed src/java/CdbWebPortal/lib/log4j-core-2.17.0.jar
Binary file not shown.
Binary file added src/java/CdbWebPortal/lib/log4j-core-2.26.0.jar
Binary file not shown.
8 changes: 4 additions & 4 deletions src/java/CdbWebPortal/nbproject/build-impl.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1026,8 +1026,8 @@ exists or setup the property manually. For example like this:
<copyfiles files="${file.reference.xmpcore-6.1.10.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
<copyfiles files="${file.reference.metadata-extractor-2.17.0.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
<copyfiles files="${file.reference.javax.xml.soap-api-1.4.0.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
<copyfiles files="${file.reference.log4j-api-2.17.0.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
<copyfiles files="${file.reference.log4j-core-2.17.0.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
<copyfiles files="${file.reference.log4j-api-2.26.0.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
<copyfiles files="${file.reference.log4j-core-2.26.0.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
<copyfiles files="${file.reference.dm-api-3.3.1.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
<copyfiles files="${file.reference.dm-base-3.3.1.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
<copyfiles files="${file.reference.flexmark-0.64.8.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
Expand Down Expand Up @@ -1089,8 +1089,8 @@ exists or setup the property manually. For example like this:
<copyfiles files="${file.reference.xmpcore-6.1.10.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
<copyfiles files="${file.reference.metadata-extractor-2.17.0.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
<copyfiles files="${file.reference.javax.xml.soap-api-1.4.0.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
<copyfiles files="${file.reference.log4j-api-2.17.0.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
<copyfiles files="${file.reference.log4j-core-2.17.0.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
<copyfiles files="${file.reference.log4j-api-2.26.0.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
<copyfiles files="${file.reference.log4j-core-2.26.0.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
<copyfiles files="${file.reference.dm-api-3.3.1.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
<copyfiles files="${file.reference.dm-base-3.3.1.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
<copyfiles files="${file.reference.flexmark-0.64.8.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
Expand Down
Loading