CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-seleniumhq-selenium--selenium-json

JSON processing library for Selenium WebDriver providing serialization and deserialization capabilities

Pending
Overview
Eval results
Files

streaming-input.mddocs/

Streaming JSON Input

Advanced JSON reading and deserialization using JsonInput for memory-efficient processing of large JSON documents. Provides fine-grained control over the parsing process, custom type coercers, and streaming access to JSON elements.

Capabilities

JsonInput Class

Streaming JSON input processor that implements Closeable for resource management.

/**
 * The JsonInput class defines the operations used to deserialize JSON strings into Java objects.
 * Provides streaming access to JSON elements and supports custom type coercion.
 */
public class JsonInput implements Closeable {
    
    // Configuration methods
    
    /**
     * Change how property setting is done. It's polite to set the value back once done processing.
     * 
     * @param setter The new PropertySetting to use
     * @return The previous PropertySetting that has just been replaced
     */
    public PropertySetting propertySetting(PropertySetting setter);
    
    /**
     * Add the specified type coercers to the set installed in the JSON coercion manager.
     * 
     * @param coercers array of zero or more TypeCoercer objects
     * @return this JsonInput object with added type coercers
     * @throws JsonException if this JsonInput has already begun processing its input
     */
    public JsonInput addCoercers(TypeCoercer<?>... coercers);
    
    /**
     * Add the specified type coercers to the set installed in the JSON coercion manager.
     * 
     * @param coercers iterable collection of TypeCoercer objects
     * @return this JsonInput object with added type coercers
     * @throws JsonException if this JsonInput has already begun processing its input
     */
    public JsonInput addCoercers(Iterable<TypeCoercer<?>> coercers);
    
    // Element inspection
    
    /**
     * Peek at the next input string character to determine the pending JSON element type.
     * 
     * @return JsonType indicating the pending JSON element type
     * @throws JsonException if unable to determine the type of the pending element
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public JsonType peek();
    
    // Primitive value reading
    
    /**
     * Read the next element of the JSON input stream as a boolean value.
     * 
     * @return true or false
     * @throws JsonException if the next element isn't the expected boolean
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public boolean nextBoolean();
    
    /**
     * Read the next element of the JSON input stream as an object property name.
     * 
     * @return JSON object property name
     * @throws JsonException if the next element isn't a string followed by a colon
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public String nextName();
    
    /**
     * Read the next element of the JSON input stream as a null object.
     * 
     * @return null object
     * @throws JsonException if the next element isn't a null
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public Object nextNull();
    
    /**
     * Read the next element of the JSON input stream as a number.
     * 
     * @return Number object
     * @throws JsonException if the next element isn't a number
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public Number nextNumber();
    
    /**
     * Read the next element of the JSON input stream as a string.
     * 
     * @return String object
     * @throws JsonException if the next element isn't a string
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public String nextString();
    
    /**
     * Read the next element of the JSON input stream as an instant.
     * 
     * @return Instant object
     * @throws JsonException if the next element isn't a Long
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public Instant nextInstant();
    
    // Container navigation
    
    /**
     * Determine whether an element is pending for the current container from the JSON input stream.
     * 
     * @return true if an element is pending; otherwise false
     * @throws JsonException if no container is open
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public boolean hasNext();
    
    /**
     * Process the opening square bracket of a JSON array.
     * 
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public void beginArray();
    
    /**
     * Process the closing square bracket of a JSON array.
     * 
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public void endArray();
    
    /**
     * Process the opening curly brace of a JSON object.
     * 
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public void beginObject();
    
    /**
     * Process the closing curly brace of a JSON object.
     * 
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public void endObject();
    
    /**
     * Discard the pending JSON property value.
     * 
     * @throws JsonException if the pending element isn't a value type
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public void skipValue();
    
    // High-level reading methods
    
    /**
     * Read the next element from the JSON input stream as the specified type.
     * 
     * @param type data type for deserialization (class or TypeToken)
     * @return object of the specified type deserialized from the JSON input stream
     *         Returns null if the input string is exhausted
     * @param <T> result type (as specified by type)
     * @throws JsonException if coercion of the next element to the specified type fails
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public <T> T read(Type type);
    
    /**
     * Read an array of elements from the JSON input stream with elements as the specified type.
     * 
     * @param type data type for deserialization (class or TypeToken)
     * @return list of objects of the specified type deserialized from the JSON input stream
     *         Returns null if the input string is exhausted
     * @param <T> result type of the item in the list (as specified by type)
     * @throws JsonException if coercion of the next element to the specified type fails
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public <T> List<T> readArray(Type type);
    
    // Resource management
    
    /**
     * Close the input stream.
     * 
     * @throws UncheckedIOException if an I/O exception is encountered
     */
    public void close();
}

JsonType Enum

Enumeration of JSON element types for parsing control.

/**
 * Used to specify the pending JSON element type.
 */
public enum JsonType {
    /** Boolean value */
    BOOLEAN,
    /** property name */
    NAME,
    /** null value */
    NULL,
    /** numeric value */
    NUMBER,
    /** start of object */
    START_MAP,
    /** end of object */
    END_MAP,
    /** start of array */
    START_COLLECTION,
    /** end of array */
    END_COLLECTION,
    /** string value */
    STRING,
    /** end of input */
    END
}

Usage Examples

Basic Streaming Reading

import org.openqa.selenium.json.Json;
import org.openqa.selenium.json.JsonInput;
import org.openqa.selenium.json.JsonType;
import java.io.StringReader;

Json json = new Json();
String jsonData = "{\"name\":\"John\",\"age\":30,\"active\":true}";

try (JsonInput input = json.newInput(new StringReader(jsonData))) {
    input.beginObject();
    
    while (input.hasNext()) {
        String propertyName = input.nextName();
        
        switch (propertyName) {
            case "name":
                String name = input.nextString();
                System.out.println("Name: " + name);
                break;
            case "age":
                Number age = input.nextNumber();
                System.out.println("Age: " + age);
                break;
            case "active":
                boolean active = input.nextBoolean();
                System.out.println("Active: " + active);
                break;
            default:
                input.skipValue(); // Skip unknown properties
        }
    }
    
    input.endObject();
}

Array Processing

String jsonArray = "[\"apple\",\"banana\",\"cherry\"]";

try (JsonInput input = json.newInput(new StringReader(jsonArray))) {
    List<String> fruits = new ArrayList<>();
    
    input.beginArray();
    while (input.hasNext()) {
        fruits.add(input.nextString());
    }
    input.endArray();
    
    System.out.println("Fruits: " + fruits);
}

// Or use the convenient readArray method
try (JsonInput input = json.newInput(new StringReader(jsonArray))) {
    List<String> fruits = input.readArray(String.class);
    System.out.println("Fruits: " + fruits);
}

Type Inspection with Peek

String jsonData = "{\"count\":42,\"message\":\"hello\",\"valid\":true}";

try (JsonInput input = json.newInput(new StringReader(jsonData))) {
    input.beginObject();
    
    while (input.hasNext()) {
        String propertyName = input.nextName();
        JsonType valueType = input.peek();
        
        switch (valueType) {
            case NUMBER:
                Number num = input.nextNumber();
                System.out.println(propertyName + " (number): " + num);
                break;
            case STRING:
                String str = input.nextString();
                System.out.println(propertyName + " (string): " + str);
                break;
            case BOOLEAN:
                boolean bool = input.nextBoolean();
                System.out.println(propertyName + " (boolean): " + bool);
                break;
            case NULL:
                input.nextNull();
                System.out.println(propertyName + " (null)");
                break;
            default:
                input.skipValue();
                System.out.println(propertyName + " (skipped)");
        }
    }
    
    input.endObject();
}

Custom Type Coercers

import org.openqa.selenium.json.TypeCoercer;
import org.openqa.selenium.json.PropertySetting;
import java.lang.reflect.Type;
import java.util.function.BiFunction;

// Custom coercer for LocalDate
public class LocalDateCoercer extends TypeCoercer<LocalDate> {
    @Override
    public boolean test(Class<?> aClass) {
        return LocalDate.class.isAssignableFrom(aClass);
    }
    
    @Override
    public BiFunction<JsonInput, PropertySetting, LocalDate> apply(Type type) {
        return (jsonInput, propertySetting) -> {
            String dateStr = jsonInput.nextString();
            return LocalDate.parse(dateStr);
        };
    }
}

// Usage
String jsonData = "{\"date\":\"2023-12-25\"}";

try (JsonInput input = json.newInput(new StringReader(jsonData))) {
    input.addCoercers(new LocalDateCoercer());
    
    input.beginObject();
    input.nextName(); // "date"
    LocalDate date = input.read(LocalDate.class);
    input.endObject();
    
    System.out.println("Date: " + date);
}

Property Setting Strategies

// Switch between property setting strategies
try (JsonInput input = json.newInput(new StringReader(jsonData))) {
    PropertySetting original = input.propertySetting(PropertySetting.BY_FIELD);
    
    // Read objects using direct field access
    MyObject obj = input.read(MyObject.class);
    
    // Restore original setting
    input.propertySetting(original);
}

Nested Object Processing

String nestedJson = """
{
    "user": {
        "name": "John",
        "preferences": {
            "theme": "dark",
            "notifications": true
        }
    },
    "lastLogin": "2023-12-25T10:30:00Z"
}
""";

try (JsonInput input = json.newInput(new StringReader(nestedJson))) {
    input.beginObject();
    
    while (input.hasNext()) {
        String key = input.nextName();
        
        if ("user".equals(key)) {
            input.beginObject();
            
            while (input.hasNext()) {
                String userKey = input.nextName();
                
                if ("name".equals(userKey)) {
                    String name = input.nextString();
                    System.out.println("User name: " + name);
                } else if ("preferences".equals(userKey)) {
                    input.beginObject();
                    
                    while (input.hasNext()) {
                        String prefKey = input.nextName();
                        
                        if ("theme".equals(prefKey)) {
                            String theme = input.nextString();
                            System.out.println("Theme: " + theme);
                        } else if ("notifications".equals(prefKey)) {
                            boolean notifications = input.nextBoolean();
                            System.out.println("Notifications: " + notifications);
                        } else {
                            input.skipValue();
                        }
                    }
                    
                    input.endObject();
                } else {
                    input.skipValue();
                }
            }
            
            input.endObject();
        } else if ("lastLogin".equals(key)) {
            Instant lastLogin = input.nextInstant();
            System.out.println("Last login: " + lastLogin);
        } else {
            input.skipValue();
        }
    }
    
    input.endObject();
}

Install with Tessl CLI

npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-json

docs

core-processing.md

index.md

streaming-input.md

streaming-output.md

type-system.md

tile.json