This guide covers advanced features and techniques in the tinystruct framework.
tinystruct includes a powerful event system that allows components to communicate without direct coupling.
// Get the event dispatcher instance
EventDispatcher dispatcher = EventDispatcher.getInstance();
// Register an event handler
dispatcher.registerHandler(UserCreatedEvent.class, event -> {
User user = event.getPayload();
System.out.println("User created: " + user.getName());
// Send welcome email
emailService.sendWelcomeEmail(user.getEmail());
});
// Dispatch an event
User newUser = userService.createUser("john@example.com", "password");
dispatcher.dispatch(new UserCreatedEvent(newUser));
public class UserCreatedEvent implements Event<User> {
private final User user;
public UserCreatedEvent(User user) {
this.user = user;
}
@Override
public User getPayload() {
return user;
}
}
public class MyApp extends AbstractApplication {
private static final EventDispatcher dispatcher = EventDispatcher.getInstance();
static {
// Register application startup handler
dispatcher.registerHandler(ApplicationStartEvent.class, event -> {
System.out.println("Application started: " + event.getPayload().getName());
});
// Register application shutdown handler
dispatcher.registerHandler(ApplicationShutdownEvent.class, event -> {
System.out.println("Application shutting down: " + event.getPayload().getName());
});
}
@Override
public void init() {
// Dispatch startup event
dispatcher.dispatch(new ApplicationStartEvent(this));
// Register shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
dispatcher.dispatch(new ApplicationShutdownEvent(this));
}));
}
}
Tinystruct provides a powerful command-line interface through its dispatcher system, allowing you to execute actions from the command line.
# Execute an action with parameters
bin/dispatcher say/"Hello World"
# Execute with named parameters
bin/dispatcher say --words "Hello World" --import tinystruct.examples.example
You can create custom CLI commands by adding the Action.Mode.CLI
mode to your action annotations:
@Action(value = "generate",
description = "POJO object generator",
mode = Action.Mode.CLI)
public String generatePOJO(String table) {
// Implementation for generating POJO from database table
return "Generated POJO for table: " + table;
}
Tinystruct includes several built-in CLI commands:
download
: Download resources from other serversexec
: Execute native commandsgenerate
: Generate POJO objectsinstall
: Install packagesmaven-wrapper
: Extract Maven Wrapperopen
: Open URLs in the default browsersay
: Output wordsset
: Set system propertiessql-execute
: Execute SQL statementssql-query
: Execute SQL queriesupdate
: Update to the latest version
Tinystruct supports multiple HTTP server implementations, allowing you to choose the one that best fits your needs.
// Start a Netty HTTP server
bin/dispatcher start --import org.tinystruct.system.NettyHttpServer
// Start a Tomcat server
bin/dispatcher start --import org.tinystruct.system.TomcatServer
// Start an Undertow server
bin/dispatcher start --import org.tinystruct.system.UndertowServer
The Context system in Tinystruct allows you to share data between different parts of your application.
// Set a context attribute
getContext().setAttribute("user", currentUser);
// Get a context attribute
User user = (User) getContext().getAttribute("user");
// Get with default value
String theme = (String) getContext().getAttribute("theme", "default");
Tinystruct provides a flexible configuration system that allows you to manage application settings.
// Get configuration value
String appName = getConfiguration().get("application.name");
// Set configuration value
getConfiguration().set("application.mode", "development");
// Load configuration from file
getConfiguration().load("config.properties");
Tinystruct offers advanced database operations through the DatabaseOperator class.
try (DatabaseOperator operator = new DatabaseOperator()) {
// Begin transaction
operator.beginTransaction();
try {
// Execute database operations
PreparedStatement stmt1 = operator.preparedStatement(
"INSERT INTO users (name) VALUES (?)",
new Object[]{"John"}
);
operator.executeUpdate(stmt1);
// Commit transaction
operator.commitTransaction();
} catch (Exception e) {
// Rollback transaction
operator.rollbackTransaction();
throw e;
}
}
try (DatabaseOperator operator = new DatabaseOperator()) {
// Begin transaction
operator.beginTransaction();
// Execute first operation
operator.executeUpdate("INSERT INTO users (name) VALUES ('John')");
// Create savepoint
Savepoint savepoint = operator.createSavepoint("AFTER_INSERT");
try {
// Execute second operation
operator.executeUpdate("UPDATE settings SET value = 'new_value'");
} catch (Exception e) {
// Roll back to savepoint
operator.rollbackTransaction(savepoint);
}
// Commit transaction
operator.commitTransaction();
}
Tinystruct provides a simple object-relational mapping system through the AbstractData class.
// Define a model class
public class User extends AbstractData {
private int id;
private String name;
private String email;
// Getters and setters
// ...
}
// Create XML mapping file in resources directory
// user.map.xml:
// <mapping>
// <class name="com.example.model.User" table="users">
// <property name="id" column="id" type="int" identifier="true"/>
// <property name="name" column="name" type="string"/>
// <property name="email" column="email" type="string"/>
// </class>
// </mapping>
// Use the model
User user = new User();
user.setName("John Doe");
user.setEmail("john@example.com");
user.append(); // Insert into database
// Find by ID
User foundUser = new User();
foundUser.setId(1);
foundUser.findOneById();
// Update
foundUser.setName("Jane Doe");
foundUser.update();
// Delete
foundUser.delete();
// Find all
List<User> allUsers = user.findAll();
// Find with condition
List<User> filteredUsers = user.findWhere("name LIKE ?", "%Doe%");
## JSON Data Handling
Tinystruct provides utilities for working with JSON data through the Builder and Builders classes.
```java
// Create JSON data
Builder builder = new Builder();
builder.put("name", "John Doe");
builder.put("age", 30);
// Create nested objects
Builder addressBuilder = new Builder();
addressBuilder.put("street", "123 Main St");
addressBuilder.put("city", "Anytown");
builder.put("address", addressBuilder);
// Create arrays
Builders hobbiesBuilder = new Builders();
hobbiesBuilder.add("Reading");
hobbiesBuilder.add("Hiking");
builder.put("hobbies", hobbiesBuilder);
// Convert to JSON string
String json = builder.toString();
// Parse JSON string
Builder parsedBuilder = new Builder();
parsedBuilder.parse(json);
// Access JSON data
String name = parsedBuilder.get("name").toString();
int age = Integer.parseInt(parsedBuilder.get("age").toString());
Builder address = (Builder) parsedBuilder.get("address");
String city = address.get("city").toString();
Builders hobbies = (Builders) parsedBuilder.get("hobbies");
String firstHobby = hobbies.get(0).toString();
Tinystruct supports internationalization for building multilingual applications.
// Get locale from request
Locale locale = request.getLocale();
// Get message bundle for locale
ResourceBundle bundle = ResourceBundle.getBundle("messages", locale);
// Get message with parameters
String greeting = MessageFormat.format(
bundle.getString("greeting"),
"John"
);
-
Action Organization: Group related actions in separate classes for better organization.
-
Error Handling: Implement proper error handling for both CLI and web applications.
-
Configuration Management: Use environment-specific configuration files for different environments.
-
Database Connections: Always use try-with-resources for database operations to ensure proper resource cleanup.
-
Transaction Management: Use transactions for operations that require atomicity.
- Explore the API Reference
- Check out the Best Practices guide