Skip to content
Merged
Changes from all commits
Commits
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
112 changes: 112 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# CLAUDE.md

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

## Project Overview

CPO (Class Persistence Object) API is a Java persistence library that maps JavaBean objects to datastore operations (CRUD). Unlike JPA/ORM tools, CPO lets you use native datastore syntax (SQL, CQL) stored externally in XML configuration files rather than annotations or code.

## Build Commands

**Prerequisites**: Java 21+, Maven 3.9+, Docker (for integration tests via Testcontainers)

```bash
# Full build including integration tests
mvn install

# Build without tests (skips Docker-dependent integration tests)
mvn install -DskipTests

# Build a specific module
mvn install -pl cpo-core
mvn install -pl cpo-jdbc
mvn install -pl cpo-cassandra

# Run tests for a specific module
mvn test -pl cpo-jdbc

# Run a single test class
mvn test -pl cpo-jdbc -Dtest=InsertObjectTest

# Apply code formatting (Google Java Format via Spotless)
mvn spotless:apply

# Check formatting without applying
mvn spotless:check

# Run PMD/CPD static analysis only
mvn pmd:check pmd:cpd-check -pl cpo-core

# Generate JaCoCo coverage report
mvn test jacoco:report -pl cpo-core
```

## Code Quality Enforcement

The build enforces these checks at compile/test phases — violations fail the build:

- **Spotless** (Google Java Format, `process-sources` phase): auto-formats Java. Run `mvn spotless:apply` before committing to avoid CI failures.
- **PMD + CPD** (`compile` phase): static analysis and copy-paste detection. Minimum token threshold is 55.
- **JaCoCo** (`test` phase): requires 80% instruction, line, and branch coverage per module.
- **License headers**: `license-maven-plugin` enforces LGPL v3 headers in all Java files. Headers use `[[` / `]]` delimiters and `==` section separator (not the standard `%L` / `%%`).

## Module Architecture

```
cpo-core — Persistence-agnostic interfaces, meta model, config, cache
cpo-jdbc — JDBC implementation of cpo-core
cpo-cassandra — Cassandra 3.x native driver implementation
cpo-plugin — Maven plugin that code-generates CPO interfaces/beans at build time
```

### Core Abstractions (cpo-core)

- **`CpoAdapter`** — primary interface for CRUD operations (`insertObject`, `retrieveBean`, `updateObject`, `deleteObject`, `retrieveBeans` returning `Stream<T>`). Entry point for application code.
- **`CpoTrxAdapter`** — extends `CpoAdapter` with explicit transaction control; obtained from `CpoAdapter.getCpoTrxAdapter()`.
- **`CpoAdapterFactory`** — creates `CpoAdapter` instances from a named config context.
- **`CpoAdapterFactoryManager`** — singleton cache that loads `cpoConfig.xml` from the classpath (env var `CPO_CONFIG` overrides path) and vends `CpoAdapterFactory` instances by config name.
- **`CpoMetaDescriptor`** — holds the JavaBean-to-datastore mapping (attributes, function groups, SQL/CQL expressions) loaded from meta XML files.
- **`CpoWhere` / `CpoOrderBy`** — programmatic query clause builders.
- **`CpoStatementFactory`** — builds datastore-specific prepared statements from `CpoMetaDescriptor` data.
- **`DataTypeMapper` / `MethodMapper`** — reflective bridges that map Java types and getter/setter methods to datastore types.

### Configuration System (two-layer XML)

1. **`cpoConfig.xml`** (loaded at startup): declares named `dataConfig` entries (JDBC or Cassandra connection details) and named `metaConfig` entries pointing to one or more meta XML files.
2. **Meta XML files** (e.g., `ValueMetaData.xml`): map JavaBean classes to function groups (INSERT, RETRIEVE, UPDATE, DELETE, EXIST, EXECUTE) and their native expressions (SQL/CQL), plus attribute-to-column bindings.

Multiple meta XML files are merged per `metaConfig`, enabling the polymorphic override pattern — a program can import a library's meta config and override class-level mappings.

### JDBC Implementation (cpo-jdbc)

- `JdbcCpoAdapter` / `JdbcCpoTrxAdapter` — concrete JDBC implementations.
- `JdbcCpoMetaDescriptor` — JDBC-specific meta with `JdbcMethodMapper` for SQL type mappings.
- `JdbcPreparedStatementFactory` / `JdbcCallableStatementFactory` — build `PreparedStatement`/`CallableStatement` from meta.
- `JdbcCpoTransform` — interface for custom type transforms; built-ins: `TransformClob`, `TransformGZipBytes`, `TransformTimestampToCalendar`, etc.
- DataSource configuration supports three modes: `dataSourceClassName` (connection pool), `driverClassName` (raw JDBC), `jndiName` (JNDI lookup). Both `readWriteConfig` (single pool) and separate `readConfig`/`writeConfig` (read/write split) are supported.

### Cassandra Implementation (cpo-cassandra)

- `CassandraCpoAdapter` — uses the Cassandra 3.x native driver; `ClusterDataSource` wraps the `Cluster` object.
- Follows the same meta XML + cpoConfig.xml pattern using CQL instead of SQL.

### Cache Layer (cpo-core)

- `CpoAdapterFactoryCache` — singleton backing store for `CpoAdapterFactory` instances, keyed by config name.
- `CpoMetaDescriptorCache` — caches parsed meta descriptors; supports hot-deploy (runtime reload).
- `CpoAdapterCache` — pools `CpoAdapter` instances.

## Testing

- Tests use **TestNG** (not JUnit). Test suites are defined in `testng.xml` per database variant (h2, mariadb, oracle, postgres, mysql, cassandra).
- Integration tests start real databases via **Testcontainers** — Docker must be running.
- H2 is the default in-process DB for fast local development; other databases require running containers.
- Test resources follow the pattern `src/test/resources/<db>/cpoConfig.xml` with filtered Maven properties (`${h2.url}`, etc.) resolved at build time.
- `JdbcSuiteListener` / `CassandraSuiteListener` handle container lifecycle (start/stop) around the test suite.

## Key Conventions

- All source files must carry the LGPL v3 license header using `[[` / `]]` delimiters; the license plugin enforces this at build time. Add headers with `mvn license:update-file-header`.
- Java 21 language level; `--release 21` in compiler config.
- JAXB-generated classes under `org.synchronoss.cpo.*config.*` and `org.synchronoss.cpo.*meta.*` subpackages (the generated ones) are excluded from Javadoc and should not be edited by hand.
- The `cpo-plugin` module generates Java interfaces and bean classes from CPO meta XML at build time — edit the XML config, not the generated sources.
Loading