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
- Semicolons: Optional. Use them only if you put multiple statements on one line.
- Parentheses: Optional for top-level method calls (e.g.,
println "Hello"). Required for nested calls or empty arguments. - Return Statements: The last expression in a method or closure is automatically returned. Explicit
returnis only needed for early exits.
2. Variables and Typing
Groovy supports "optional typing." You can choose between dynamic flexibility and static enforcement.
- Dynamic (
def): The type is inferred at runtime. Useful for rapid prototyping and local variables. - Static (e.g.,
String,Integer): Enforces type safety at compile time. Recommended for public APIs or complex domain models.
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:.classvs.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 Javaclassobject. If you need to check the type of a Map, you must use the methodship.getClass().
3. Groovy Truth
Conditional logic in Groovy is broader than just true or false. The following evaluate to false (everything else is true):
null- Boolean
false - Zero
0or0.0 - Empty Strings
"" - Empty Collections
[]or[:]
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):
- Belongs to the class.
- Shared by all users across the entire application.
- Use Case: Caches, game boards, configuration, utility functions.
- Risk: Not thread-safe; one user's action can affect another user.
Instance (Request State):
- Belongs to the object instance.
- Created fresh for every HTTP request.
- Use Case: User session data, form inputs, temporary variables.
3. Spaceport Class Enhancements
Spaceport adds domain-specific methods to standard classes to speed up web development.
Strings:
.kebab(): "User Name" -\> "user-name".slugify(): "My Post\!" -\> "my-post".clean(): Sanitizes HTML inputs.
Numbers:
.money(): Formats as currency..minutes(),.days(): Converts time to milliseconds.
Logic:
.if { ... }: Returns the string if the closure is true, otherwise empty string.- Example:
"<a href='/admin'>Admin</a>".if { user.isAdmin }
# 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.
@ToString: Automatically generates atoString()method including all properties.@EqualsAndHashCode: GeneratesequalsandhashCodebased on properties.@Canonical: Combines@ToString,@EqualsAndHashCode, and a Tuple constructor.@Singleton: Makes the class a singleton (one instance only).
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.
t.getString('username'): Safely gets a string.t.getInteger('age'): Safely parses an integer.t.getBool('active'): Handles "true", "on", "yes", and checkbox states.
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.
- Start Here: Tic-Tac-Toe Tutorial
## 2. Consult the Ancient Texts
Spaceport documentation covers the framework, but for deep language questions, go to the source.
- Official Docs: groovy-lang.org
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:
- Source Modules: Learn how to organize your backend logic and handle the lifecycle of your Groovy classes.
- Alerts: Understand how to route HTTP traffic to your code and build an event-driven architecture.
- Launchpad: Master the art of embedding Groovy directly into your HTML for dynamic interfaces.
- Cargo: Deep dive into reactive state management and data persistence.
- Class Enhancements: Memorize the shortcut methods Spaceport adds to standard Java classes to speed up your workflow.
Welcome to the fleet. Your journey to becoming a true Groovy Luminary begins now.
SPACEPORT DOCS