Skip to content

Latest commit

 

History

History
198 lines (161 loc) · 8.21 KB

File metadata and controls

198 lines (161 loc) · 8.21 KB

Copilot Instructions for java.evolved

Project Overview

This is a static site showcasing modern Java patterns vs legacy approaches. It is hosted on GitHub Pages at https://javaevolved.github.io.

Architecture

Source of Truth: JSON Files

Each pattern is defined as a JSON file under content/category/:

content/language/type-inference-with-var.json
content/collections/immutable-list-creation.json
content/streams/stream-tolist.json
...

Categories: language, collections, strings, streams, concurrency, io, errors, datetime, security, tooling, enterprise

Generated Files (DO NOT EDIT)

The following are generated by html-generators/generate.java and must not be edited directly:

  • site/index.html — English homepage with preview cards (generated from templates/index.html)
  • site/language/*.html, site/collections/*.html, etc. — English detail pages
  • site/data/snippets.json — English aggregated search index
  • site/{locale}/index.html — localized homepage (e.g., site/es/index.html)
  • site/{locale}/language/*.html, etc. — localized detail pages
  • site/{locale}/data/snippets.json — localized search index

Run jbang html-generators/generate.java to rebuild all generated files from the JSON sources and translations.

Manually Maintained Files

  • site/app.js — client-side search, filtering, code highlighting, locale detection
  • site/styles.css — all styling
  • templates/slug-template.html — HTML template with {{placeholder}} tokens (content + UI strings) used by the generator
  • templates/index.html — homepage template with {{tipCards}}, {{snippetCount}}, and UI string placeholders
  • templates/index-card.html — preview card template for the homepage grid
  • html-generators/categories.properties — category ID → display name mapping
  • html-generators/locales.properties — supported locales registry (locale=Display name)
  • translations/strings/{locale}.yaml — UI strings per locale (labels, nav, footer, etc.)
  • translations/content/{locale}/ — translated pattern JSON files (partial, translatable fields only)

Project Structure

content/            # English content JSON files (source of truth, one per pattern)
proof/              # Proof scripts — one JBang .java file per pattern, proving it compiles
  language/         # e.g. proof/language/TypeInferenceWithVar.java
  collections/      # e.g. proof/collections/ImmutableListCreation.java
  ...               # mirrors content/ category structure
translations/       # All i18n artifacts
  strings/          # UI strings per locale (en.yaml, es.yaml, pt-BR.yaml)
  content/          # Translated pattern files per locale (partial, translatable fields only)
    es/             # Spanish translations (mirrors content/ folder structure)
    pt-BR/          # Brazilian Portuguese translations
site/               # Deployable site (static assets + generated HTML)
  es/               # Generated Spanish pages
  pt-BR/            # Generated Portuguese pages
templates/          # HTML templates with {{…}} tokens for content + UI strings
html-generators/    # Build scripts, categories.properties, locales.properties
specs/              # Feature specifications (e.g., i18n-spec.md)

JSON Snippet Schema

Each content/category/slug.json file has this structure:

{
  "id": 1,
  "slug": "type-inference-with-var",
  "title": "Type inference with var",
  "category": "language",
  "difficulty": "beginner|intermediate|advanced",
  "jdkVersion": "10",
  "oldLabel": "Java 8",
  "modernLabel": "Java 10+",
  "oldApproach": "Explicit Types",
  "modernApproach": "var keyword",
  "oldCode": "// old way...",
  "modernCode": "// modern way...",
  "summary": "One-line description.",
  "explanation": "How it works paragraph.",
  "whyModernWins": [
    { "icon": "", "title": "Short title", "desc": "One sentence." },
    { "icon": "👁", "title": "Short title", "desc": "One sentence." },
    { "icon": "🔒", "title": "Short title", "desc": "One sentence." }
  ],
  "support": {
    "state": "available",
    "description": "Widely available since JDK 10 (March 2018)"
  },
  "prev": "category/slug-of-previous",
  "next": "category/slug-of-next",
  "related": [
    "category/slug-1",
    "category/slug-2",
    "category/slug-3"
  ],
  "docs": [
    { "title": "Javadoc or Guide Title", "href": "https://docs.oracle.com/..." }
  ]
}

Key Rules

  • slug must match the filename (without .json)
  • category must match the parent folder name
  • whyModernWins must have exactly 3 entries
  • related must have exactly 3 entries (as category/slug paths)
  • docs must have at least 1 entry linking to Javadoc or Oracle documentation
  • prev/next are category/slug paths or null for first/last
  • Code in oldCode/modernCode uses \n for newlines
  • proofCode is optional — a self-contained JShell snippet (with default imports available) that proves the modern approach compiles and runs correctly. Run jbang html-generators/proof.java to verify all proof snippets.

Category Display Names

Categories and their display names are defined in html-generators/categories.properties:

ID Display
language Language
collections Collections
strings Strings
streams Streams
concurrency Concurrency
io I/O
errors Errors
datetime Date/Time
security Security
tooling Tooling
enterprise Enterprise

Adding a New Pattern

  1. Create content/category/new-slug.json with all required fields
  2. Update prev/next in the adjacent patterns' JSON files
  3. Run jbang html-generators/generate.java
  4. Add a proof script at proof/category/SlugName.java (JBang, //JAVA 25+) — run jbang html-generators/proof.java to verify
  5. (Optional) Create translated content files under translations/content/{locale}/category/new-slug.json with only translatable fields — or let the AI translation workflow handle it

Internationalization (i18n)

The site supports multiple languages. See specs/i18n/i18n-spec.md for the full specification.

Key Concepts

  • UI strings: Hard-coded template text (labels, nav, footer) is extracted into translations/strings/{locale}.yaml. Templates use {{dotted.key}} tokens (e.g., {{nav.allPatterns}}, {{sections.codeComparison}}). Missing keys fall back to the English value with a build-time warning.
  • Content translations: Translated pattern files under translations/content/{locale}/ contain only translatable fields (title, summary, explanation, oldApproach, modernApproach, whyModernWins, support.description). All other fields (oldCode, modernCode, slug, id, prev, next, related, docs, etc.) are always taken from the English source.
  • Locale registry: html-generators/locales.properties lists supported locales (format: locale=Display name). The first entry is the default.
  • English is a first-class locale: All locales — including English — go through the same build pipeline.
  • Fallback: If a pattern has no translation file for a locale, the English content is used and an "untranslated" banner is shown.

Supported Locales

Defined in html-generators/locales.properties:

Locale Display Name
en English
es Español
pt-BR Português (Brasil)

Content Translation File Example

Translation files contain only translatable fields — no structural data:

// translations/content/pt-BR/language/type-inference-with-var.json
{
  "title": "Inferência de tipo com var",
  "oldApproach": "Tipos explícitos",
  "modernApproach": "Palavra-chave var",
  "summary": "Use var para deixar o compilador inferir o tipo local.",
  "explanation": "...",
  "whyModernWins": [
    { "icon": "", "title": "Menos ruído", "desc": "..." },
    { "icon": "👁",  "title": "Mais legível", "desc": "..." },
    { "icon": "🔒", "title": "Seguro", "desc": "..." }
  ],
  "support": {
    "description": "Amplamente disponível desde o JDK 10 (março de 2018)"
  }
}

Local Development

jbang html-generators/generate.java  # Build HTML pages + snippets.json
jwebserver -d site -p 8090              # Serve locally