Apache Groovy is a powerful multi-faceted programming language for the JVM platform
—
Enhanced collection classes, observable data structures, and utility functions that extend Java's collection framework with Groovy-specific features and dynamic behavior. These utilities provide event-driven collections, default value handling, and enhanced data structure capabilities.
Collections that fire property change events when modified.
class ObservableList<E> extends ArrayList<E> {
/**
* Creates an empty observable list.
*/
ObservableList();
/**
* Creates an observable list with initial capacity.
*/
ObservableList(int initialCapacity);
/**
* Creates an observable list from another collection.
*/
ObservableList(Collection<? extends E> c);
/**
* Adds a property change listener.
*/
void addPropertyChangeListener(PropertyChangeListener listener);
/**
* Removes a property change listener.
*/
void removePropertyChangeListener(PropertyChangeListener listener);
/**
* Adds a property change listener for a specific property.
*/
void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);
/**
* Removes a property change listener for a specific property.
*/
void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
/**
* Gets all property change listeners.
*/
PropertyChangeListener[] getPropertyChangeListeners();
/**
* Gets property change listeners for a specific property.
*/
PropertyChangeListener[] getPropertyChangeListeners(String propertyName);
/**
* Fires a property change event.
*/
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue);
/**
* Fires an indexed property change event.
*/
protected void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue);
}
class ObservableMap<K, V> extends LinkedHashMap<K, V> {
/**
* Creates an empty observable map.
*/
ObservableMap();
/**
* Creates an observable map with initial capacity.
*/
ObservableMap(int initialCapacity);
/**
* Creates an observable map from another map.
*/
ObservableMap(Map<? extends K, ? extends V> m);
/**
* Adds a property change listener.
*/
void addPropertyChangeListener(PropertyChangeListener listener);
/**
* Removes a property change listener.
*/
void removePropertyChangeListener(PropertyChangeListener listener);
/**
* Adds a property change listener for a specific property.
*/
void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);
/**
* Removes a property change listener for a specific property.
*/
void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
/**
* Gets all property change listeners.
*/
PropertyChangeListener[] getPropertyChangeListeners();
/**
* Fires a property change event.
*/
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue);
}
class ObservableSet<E> extends LinkedHashSet<E> {
/**
* Creates an empty observable set.
*/
ObservableSet();
/**
* Creates an observable set with initial capacity.
*/
ObservableSet(int initialCapacity);
/**
* Creates an observable set from another collection.
*/
ObservableSet(Collection<? extends E> c);
/**
* Adds a property change listener.
*/
void addPropertyChangeListener(PropertyChangeListener listener);
/**
* Removes a property change listener.
*/
void removePropertyChangeListener(PropertyChangeListener listener);
/**
* Adds a property change listener for a specific property.
*/
void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);
/**
* Removes a property change listener for a specific property.
*/
void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
/**
* Gets all property change listeners.
*/
PropertyChangeListener[] getPropertyChangeListeners();
}Collections that provide default values for missing keys or out-of-bounds access.
class ListWithDefault<T> implements List<T> {
/**
* Creates a list with default value provider.
*/
static <T> ListWithDefault<T> withDefault(Closure<T> defaultValue);
/**
* Creates a list with default value provider from existing list.
*/
static <T> ListWithDefault<T> withDefault(List<T> list, Closure<T> defaultValue);
/**
* Creates a list with lazy default value provider.
*/
static <T> ListWithDefault<T> withLazyDefault(Closure<T> defaultValue);
/**
* Creates a list with lazy default value provider from existing list.
*/
static <T> ListWithDefault<T> withLazyDefault(List<T> list, Closure<T> defaultValue);
/**
* Creates a list with eager default value provider.
*/
static <T> ListWithDefault<T> withEagerDefault(Closure<T> defaultValue);
/**
* Creates a list with eager default value provider from existing list.
*/
static <T> ListWithDefault<T> withEagerDefault(List<T> list, Closure<T> defaultValue);
/**
* Gets the default value for the given index.
*/
T getDefaultValue(int index);
/**
* Checks if the default value is lazy.
*/
boolean isLazyDefaultValues();
/**
* Checks if the default value is eager.
*/
boolean isEagerDefaultValues();
}
class MapWithDefault<K, V> implements Map<K, V> {
/**
* Creates a map with default value provider.
*/
static <K, V> MapWithDefault<K, V> withDefault(Closure<V> defaultValue);
/**
* Creates a map with default value provider from existing map.
*/
static <K, V> MapWithDefault<K, V> withDefault(Map<K, V> map, Closure<V> defaultValue);
/**
* Creates a map with lazy default value provider.
*/
static <K, V> MapWithDefault<K, V> withLazyDefault(Closure<V> defaultValue);
/**
* Creates a map with lazy default value provider from existing map.
*/
static <K, V> MapWithDefault<K, V> withLazyDefault(Map<K, V> map, Closure<V> defaultValue);
/**
* Creates a map with eager default value provider.
*/
static <K, V> MapWithDefault<K, V> withEagerDefault(Closure<V> defaultValue);
/**
* Creates a map with eager default value provider from existing map.
*/
static <K, V> MapWithDefault<K, V> withEagerDefault(Map<K, V> map, Closure<V> defaultValue);
/**
* Gets the default value for the given key.
*/
V getDefaultValue(K key);
/**
* Checks if the default value is lazy.
*/
boolean isLazyDefaultValues();
/**
* Checks if the default value is eager.
*/
boolean isEagerDefaultValues();
}Generic tree node implementation for data processing and XML handling.
class Node implements Serializable, Cloneable {
/**
* Creates a Node with the given name.
*/
Node(Object name);
/**
* Creates a Node with name and value.
*/
Node(Object name, Object value);
/**
* Creates a Node with name and attributes.
*/
Node(Object name, Map<String, String> attributes);
/**
* Creates a Node with name, attributes, and value.
*/
Node(Object name, Map<String, String> attributes, Object value);
/**
* Creates a Node with parent, name, and value.
*/
Node(Node parent, Object name, Object value);
/**
* Creates a Node with parent, name, attributes, and value.
*/
Node(Node parent, Object name, Map<String, String> attributes, Object value);
/**
* Gets the name of this node.
*/
Object name();
/**
* Gets the value of this node.
*/
Object value();
/**
* Sets the value of this node.
*/
void setValue(Object value);
/**
* Gets the attributes of this node.
*/
Map<String, String> attributes();
/**
* Gets an attribute value.
*/
Object attribute(Object key);
/**
* Gets all child nodes.
*/
List<Node> children();
/**
* Gets the parent node.
*/
Node parent();
/**
* Sets the parent node.
*/
void setParent(Node parent);
/**
* Gets the text content of this node and its children.
*/
String text();
/**
* Gets child nodes with the given name.
*/
NodeList get(Object key);
/**
* Gets child node at the given index.
*/
Object get(int index);
/**
* Gets a property value (attribute or child).
*/
Object getProperty(String key);
/**
* Sets a property value (creates child or sets attribute).
*/
void setProperty(String key, Object value);
/**
* Appends a child node.
*/
Node append(Node child);
/**
* Removes a child node.
*/
boolean remove(Node child);
/**
* Adds a child node.
*/
void add(Node child);
/**
* Replaces this node with another.
*/
void replaceNode(Node replacement);
/**
* Finds child nodes matching the closure condition.
*/
NodeList depthFirst(Closure closure);
/**
* Finds child nodes in breadth-first order matching the closure.
*/
NodeList breadthFirst(Closure closure);
}
class NodeBuilder extends BuilderSupport {
/**
* Creates a NodeBuilder.
*/
NodeBuilder();
/**
* Creates a named node.
*/
protected Object createNode(Object name);
/**
* Creates a named node with value.
*/
protected Object createNode(Object name, Object value);
/**
* Creates a named node with attributes.
*/
protected Object createNode(Object name, Map attributes);
/**
* Creates a named node with attributes and value.
*/
protected Object createNode(Object name, Map attributes, Object value);
/**
* Sets the parent-child relationship.
*/
protected void setParent(Object parent, Object child);
/**
* Called when node creation is complete.
*/
protected void nodeCompleted(Object parent, Object node);
}Object inspection and introspection utilities.
class Inspector {
/**
* Creates an Inspector for the given object.
*/
Inspector(Object objectUnderInspection);
/**
* Inspects the object and returns a string representation.
*/
String inspect();
/**
* Prints the inspection to the console.
*/
void print();
/**
* Prints the inspection to a PrintStream.
*/
void print(PrintStream out);
/**
* Gets inspection data as a list of strings.
*/
String[] getPropertyInfo();
/**
* Gets inspection data as a list of strings with sorting.
*/
String[] getPropertyInfo(Comparator<String> comparator);
/**
* Gets meta information about the object's class.
*/
String[] getMetaInfo();
/**
* Gets public field information.
*/
String[] getPublicFieldInfo();
/**
* Gets property information.
*/
String[] getPropertyInfo();
}Simple logging support for Groovy applications.
class Log {
/**
* Gets a logger for the given class.
*/
static Logger getLogger(Class<?> clazz);
/**
* Gets a logger with the given name.
*/
static Logger getLogger(String name);
/**
* Sets the logging level.
*/
static void setLevel(Level level);
/**
* Gets the current logging level.
*/
static Level getLevel();
}
interface Logger {
/**
* Logs a debug message.
*/
void debug(Object message);
/**
* Logs an info message.
*/
void info(Object message);
/**
* Logs a warning message.
*/
void warn(Object message);
/**
* Logs an error message.
*/
void error(Object message);
/**
* Logs an error message with throwable.
*/
void error(Object message, Throwable t);
/**
* Checks if debug logging is enabled.
*/
boolean isDebugEnabled();
/**
* Checks if info logging is enabled.
*/
boolean isInfoEnabled();
/**
* Checks if warn logging is enabled.
*/
boolean isWarnEnabled();
/**
* Checks if error logging is enabled.
*/
boolean isErrorEnabled();
}import groovy.util.ObservableList;
import groovy.util.ObservableMap;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
// Create observable list with listener
ObservableList<String> list = new ObservableList<>();
list.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("Property " + evt.getPropertyName() +
" changed from " + evt.getOldValue() +
" to " + evt.getNewValue());
}
});
// Add elements - will fire events
list.add("first");
list.add("second");
list.set(0, "modified");
// Create observable map
ObservableMap<String, Integer> map = new ObservableMap<>();
map.addPropertyChangeListener("size", new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("Map size changed to " + evt.getNewValue());
}
});
map.put("one", 1);
map.put("two", 2);import groovy.util.ListWithDefault;
import groovy.util.MapWithDefault;
import groovy.lang.Closure;
// Create list with default values
ListWithDefault<String> list = ListWithDefault.withDefault(new Closure<String>(null) {
public String doCall(Object index) {
return "default-" + index;
}
});
// Access beyond bounds returns default value
System.out.println(list.get(5)); // Prints: default-5
// Create map with default values
MapWithDefault<String, List<String>> map = MapWithDefault.withDefault(new Closure<List<String>>(null) {
public List<String> doCall(Object key) {
return new ArrayList<String>();
}
});
// Access missing key returns default value
List<String> defaultList = map.get("nonexistent");
defaultList.add("item");
map.put("nonexistent", defaultList);import groovy.util.Node;
import groovy.util.NodeBuilder;
import groovy.util.NodeList;
// Create node tree with builder
NodeBuilder builder = new NodeBuilder();
Node root = (Node) builder.invokeMethod("root", new Object[]{});
Node person = new Node(root, "person", new HashMap<String, String>());
person.attributes().put("id", "1");
new Node(person, "name", "John Doe");
new Node(person, "age", "30");
new Node(person, "email", "john@example.com");
// Navigate and process
System.out.println("Root name: " + root.name());
System.out.println("Person ID: " + person.attribute("id"));
NodeList children = root.get("person");
for (Node child : children) {
System.out.println("Child: " + child.name());
NodeList nameNodes = child.get("name");
if (!nameNodes.isEmpty()) {
System.out.println("Name: " + ((Node)nameNodes.get(0)).value());
}
}
// Find nodes using closure
NodeList foundNodes = root.depthFirst(new Closure<Boolean>(null) {
public Boolean doCall(Object node) {
return ((Node)node).name().equals("email");
}
});
for (Node found : foundNodes) {
System.out.println("Found email: " + found.value());
}import groovy.inspect.Inspector;
// Inspect an object
String testString = "Hello World";
Inspector inspector = new Inspector(testString);
// Print inspection to console
inspector.print();
// Get inspection data
String[] propertyInfo = inspector.getPropertyInfo();
for (String info : propertyInfo) {
System.out.println(info);
}
// Get meta information
String[] metaInfo = inspector.getMetaInfo();
for (String info : metaInfo) {
System.out.println(info);
}Install with Tessl CLI
npx tessl i tessl/maven-org-codehaus-groovy--groovy