jt-oddl

An Open Data Description Language parser for Java 9+

License

License

GroupId

GroupId

com.github.mdzhb
ArtifactId

ArtifactId

jt-oddl
Last Version

Last Version

1.0.1
Release Date

Release Date

Type

Type

jar
Description

Description

jt-oddl
An Open Data Description Language parser for Java 9+
Project URL

Project URL

https://github.com/MDZhB/jt-oddl
Source Code Management

Source Code Management

https://github.com/MDZhB/jt-oddl

Download jt-oddl

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.mdzhb/jt-oddl/ -->
<dependency>
    <groupId>com.github.mdzhb</groupId>
    <artifactId>jt-oddl</artifactId>
    <version>1.0.1</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.mdzhb/jt-oddl/
implementation 'com.github.mdzhb:jt-oddl:1.0.1'
// https://jarcasting.com/artifacts/com.github.mdzhb/jt-oddl/
implementation ("com.github.mdzhb:jt-oddl:1.0.1")
'com.github.mdzhb:jt-oddl:jar:1.0.1'
<dependency org="com.github.mdzhb" name="jt-oddl" rev="1.0.1">
  <artifact name="jt-oddl" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.mdzhb', module='jt-oddl', version='1.0.1')
)
libraryDependencies += "com.github.mdzhb" % "jt-oddl" % "1.0.1"
[com.github.mdzhb/jt-oddl "1.0.1"]

Dependencies

test (1)

Group / Artifact Type Version
junit : junit jar 4.12

Project Modules

There are no modules declared in this project.

jt-oddl

Javadocs

Overview

jt-oddl is an Open Data Description Language parser written in Java.

Getting started

Maven

Add the following to the <dependencies> element in your pom.xml:

<dependency>
  <groupId>com.github.mdzhb</groupId>
  <artifactId>jt-oddl</artifactId>
  <version>1.0.1</version>
</dependency>

In Code

To parse an OpenDDL file, you need an ODDLReader and an implementation of the ODDLListener interface. The ODDLReader parses text read from a Reader or InputStream. Every time the ODDLReader encounters a valid language construct in the input, it calls the appropriate method in its ODDLListener.

Consider the following example listener. For brevity, it only implements three of the methods specified in the ODDLListener interface.

// this class generates a list of Structure objects; imagine the Structure class is defined elsewhere in your code
class StructureListener implements ODDLListener<List<Structure>> {
    
    /** this is the collection of structures our listener will return */
    private final List<Structure>  structures = new ArrayList<>();
    
    /** a stack helps us handle nested structures */
    private final Deque<Structure> stack = new ArrayDeque<>();
    
    // this method is called when the reader encounters the beginning of a custom structure
    @Override
    public void beginCustomStructure(IdentifierToken identifier, NameToken name, PropertyMap properties) {
        stack.push(new Structure(identifier, name, properties));
    }
    
    // this method is called when the reader reaches the end of a custom structure (i.e. the closing brace)
    @Override
    public void endCustomStructure(IdentifierToken identifier, NameToken name, PropertyMap properties) {
        Structure struct = stack.pop();
        if (stack.isEmpty()) { // this is a top-level structure
            structures.add(struct);
        } else { // this is a child structure
            stack.peek().addChildStructure(struct);
        }
    }
    
    // this method is called when the reader reaches end of file
    @Override
    public List<Structure> end(int row, int col) {
        return structures; // this return value is the object returned by ODDLReader.read()
    }
}

You would use the StructureListener like this:

try (InputStream in = Files.newInputStream(Paths.get("myfile.oddl"))) {
    List<Structure> structures = new ODDLReader(in).read(new StructureListener());
    // operate on your list of Structures...
}

ODDLToken defines methods that convert tokens to more specific types without casting. This is useful when handling structure properties in your listener implementation, for example.

@Override
public void beginCustomStructure(IdentifierToken identifier, NameToken name, PropertyMap properties) {
    PropertyValueToken token = properties.get("propertyName");
    if (token.isFloat()) { // is this a float literal?
        FloatToken ft = token.asFloat(); // it is, so this line is valid
    }
}

If handling a large number of token types, it may be wiser to use a switch statement:

switch (token.getType()) {
    case BOOL:
        BoolToken bt = token.asBool().getValue();
        break;
    case FLOAT:
        FloatToken ft = token.asFloat().getValue();
        break;
    // etc.
}

These "downcasting" methods throw an IllegalArgumentException when the token is not an instance of the desired class.

Versions

Version
1.0.1
1.0.0