SPACEPORT DOCS

Groovy Luminary Certification

Welcome to the comprehensive guide to Apache Groovy within the Spaceport ecosystem.

This certification course is designed to transform developers into Groovy experts. By the end of this program, you will master everything from basic syntax and "Groovy Truth" to advanced metaprogramming and Spaceport-specific architectural patterns.

Course Philosophy: Groovy is designed to remove the friction from Java development. It reduces boilerplate, introduces powerful functional programming concepts, and allows for concise, expressive code that is easier to read and maintain.

Module 01: Core Syntax & Essentials

Groovy compiles to Java bytecode and runs on the JVM. It is 100% compatible with Java libraries, but it offers a more streamlined syntax.

1. The Basics: Less Boilerplate

2. Variables and Typing

Groovy supports "optional typing." You can choose between dynamic flexibility and static enforcement.

3. Properties vs. Fields

In Java, you write private fields and public getters/setters. In Groovy, you simply define a property.

class Starship {
    // This automatically generates:
    // 1. A private backing field
    // 2. A public getter: getRegistry()
    // 3. A public setter: setRegistry()
    String registry
}

def ship = new Starship()
ship.registry = "NCC-1701"  // Calls setRegistry()
println ship.registry       // Calls getRegistry()

4. Operators

Groovy introduces operators that drastically reduce conditional logic.

Safe Navigation (?.): Prevents NullPointerException. If the object is null, the expression returns null instead of crashing.

ship?.captain?.name

Elvis Operator (?:): A shorthand for "use this value, or use a default if null/false."

def user = name ?: "Guest" (Equivalent to: name != null ? name : "Guest")

Spaceship Operator (<=>): Used for comparison. Returns -1, 0, or 1.

list.sort { a, b -> a <=> b }

Module 02: Data Structures & Groovy Truth

Groovy treats collections as first-class citizens with literal syntax.

## 1. Lists

Groovy Lists are dynamically resizing arrays (java.util.ArrayList by default).

def crew = ["Sisko", "Kira", "Dax"]

crew << "Bashir"      // Append using left-shift
println crew[0]       // Access first item
println crew[-1]      // Access last item (negative index)

## 2. Maps

Maps are key-value pairs (java.util.LinkedHashMap by default).

def ship = [
    name: "Defiant",
    registry: "NX-74205"
]

println ship.name          // Property access
println ship['registry']   // Subscript access
ship.class = "Escort"      // Add new key
Gotcha: .class vs .getClass()—Because Groovy allows property access for map keys (like ship.name), accessing ship.class will attempt to look up a key named "class" inside the map. It will not return the Java class object. If you need to check the type of a Map, you must use the method ship.getClass().

3. Groovy Truth

Conditional logic in Groovy is broader than just true or false. The following evaluate to false (everything else is true):

This allows for concise checks:

// Checks if user is not null, and name is not empty/null
if (user?.name) { 
    // ... 
}

# Module 03: Functional Programming

Closures are the heart of Groovy. They are anonymous blocks of code that can be passed as variables. They are used for iteration, resource handling, and callbacks.

1. Syntax & The it Parameter

A closure is defined with {}. If a closure takes a single argument, you can refer to it implicitly as it.

// Implicit parameter
[1, 2, 3].each { println it }

// Explicit named parameter (cleaner for complex logic)
[1, 2, 3].each { number -> 
    println "Number is $number" 
}

2. Collection Methods—The GDK

Groovy adds powerful functional methods to standard Java collections.

Method Description Example
each Iterates through items. list.each { ... }
collect Transforms items (Map). list.collect { it * 2 }
find Returns the first match. list.find { it > 5 }
findAll Returns all matches. list.findAll { it.active }
any Returns true if any match. list.any { it.failed }
every Returns true if all match. list.every { it.passed }

Module 04: Spaceport Architecture

Understanding how Groovy fits into Spaceport's "Source Modules" is critical for managing state and memory.

1. Source Modules

Source Modules are Groovy classes located in your /modules directory. They separate your logic from your view templates.

2. Static vs. Instance Scope

Because Spaceport handles web requests, understanding variable scope is a security and stability requirement.

static (Shared State):

Instance (Request State):

3. Spaceport Class Enhancements

Spaceport adds domain-specific methods to standard classes to speed up web development.

Strings:

Numbers:

Logic:

# Module 05: Advanced Engineering

Metaprogramming allows you to modify classes at runtime or compile time. This allows for "magic" features and Domain Specific Languages (DSLs).

1. Runtime: ExpandoMetaClass

You can add methods to any class, even final Java classes like String.

// Add a 'shout' method to String
String.metaClass.shout = { ->
    return delegate.toUpperCase() + "!"
}

println "hello".shout() // HELLO!

2. Compile Time: AST Transformations

Groovy provides annotations that modify the Abstract Syntax Tree (AST) during compilation, generating complex code for you.

Module 06: The Bridge—Launchpad Templates

In Spaceport, Groovy is the engine for the UI. Launchpad templates (.ghtml) mix HTML with Groovy logic.

1. The Transmission Object—t

When a user clicks a button or submits a form, the data is sent to a closure. The argument (usually named t) is the Transmission.

2. Server Actions

Logic runs on the server via closures.

<%
    // Define the action
    def updateProfile = { t ->
        def name = t.getString('name')
        // Return a map of instructions for the client
        return [
            '#message': "Profile updated for $name",
            'val_name': "" // Clear the input
        ]
    }
%>

<form on-submit=${ _{ t -> updateProfile(t) } }>
    <input id="name" name="name">
    <button>Update</button>
    <div id="message"></div>
</form>

3. Cargo—Reactive State

Cargo objects act as reactive memory. When modified on the server, any HTML bound to them updates automatically without a page reload.

<%
    def cart = Cargo.fromStore('cart')
    
    def addItem = {
        // Logic updates the data
        cart.inc('items')
        // No return needed; UI updates automatically
    }
%>

<span>Items: ${{ cart.items }}</span>
<button on-click=${ _{ addItem() } }>Add</button>

Path to Luminary Status

There is no single final exam that can declare you a "Groovy Luminary." True expertise comes from writing code, encountering edge cases, and building real applications within the Spaceport architecture.

To earn your stripes, we recommend the following flight path:

1. Build the "Tic-Tac-Toe" Application

This is the rite of passage for all new Spaceport developers. It forces you to use Source Modules, Launchpad Templates, and Static State in a real scenario.

## 2. Consult the Ancient Texts

Spaceport documentation covers the framework, but for deep language questions, go to the source.

3. Master the Spaceport Systems

Once you are comfortable with the syntax, dive deeper into the specific systems that make Spaceport unique. Read these documents next:

Welcome to the fleet. Your journey to becoming a true Groovy Luminary begins now.