Looking inside – bottom-up
Strengths and Characteristics
Japaki builds on standard Java classes and apis, using already existing
implementation and allowing better interaction with other frameworks.
Japaki is organized in several layers allowing
amendments
and extensions on every layer.
Packages
Japaki consists of six packages that are based on each other:
- basic
- contains helper classes of general use, not related to parsing in particular;
- beans
- defines properties and beans,
- io
- provides helper classes for in- and output,
- text
- contains the parsers,
- kit
- offers the classes to create parsers,
- self
- the topmost package to interpret syntax definitions.
Core Classes
The following graphic shows the main classes of japaki.

The starting point is the
Format class in the
java.text
package
with its basic methods
format
and
parseObject.
A format is a rule how to transform a java object into a string.
A format can be parameterized by some fields like
- a locale,
- a style,
- a pattern,
- format symbols.
The japaki parser differs from the standard Format in three aspects:
- It uses generics: A format or parser only applies to certain types of objects
- The NumberFormat to
numbers,
- The DateFormat to
dates,
- …
This is not reflected in the Format
,
the parseObject
-method of which returns an
Object,
because it was written before
Generics came up.
- The standard java class
ParsePosition
is determined by a single integer and therefore limited to (single line) strings.
The japaki positions
ParseReader
and
ParseWriter
are intended for files and therefore also contain a line number and a
newLine method.
- The standard format and parse methods deliver the result as the return
value from the method. Japaki methods do not return a value but store the
result in an object using properties.
A property tells the parser how and where to store and retrieve the value.
The connection between a
Parser
and a Format
is established by the
LeafParser
class that creates a parser out of a Format
.
Say, we have a bean with a property foo
:
public String getFoo(){ return foo;}
public void setFoo(String foo){ this.foo = foo;}
In order to pass the get
- and set
-method to a parser they have to be converted into
an object. This is the idea of the
Property-interface.
A property tells the parser how and where to store and retrieve the value
in the object by virtue of
getValue and
setValue methods.
The bean package contains a set of properties for basic java classes.
Generic Beans
One of the strengths of Japaki comes from abstracting a property into its own class.
This makes the path to the next step:
A bean that provides a list of all its properties.
This is of course similar to using reflection,
where a list of all getter methods can be obtained using reflection
methods.
Reflection allows using common Java beans which are widespread in the java world,
while generic beans allows checking of dependencies at compile time.
ReflectionProperty and
JavaBeanInspector
support the use of reflection.
One of the main characteristics of a more complex syntax is
that a parser is defined using another parser.
This calls for a place where the yet defined parsers can be looked up.
This function is adopted by the
ParserStore class.
To be flexible the ParserStore does not store parsers but factory classes
that create a certain type of parsers based on its construction parameters.
This factory class is called a
ParserMold.
So the ParserStore contains
- a mapping of names to ParserMolds.
Typically only one parser is needed for a class type, so the next thing the ParserStore has is
- a mapping of classes to ParserMolds
The class can be derived from the property, so if the default parser for
the class is used, the parser name can be omitted.
The simplest way to retrieve a parser is with a property using
findParser.
As a proof of concept, japaki is applied on itself or, strictly speaking, on the
syntax definition strings.
The meta definition parser is defined in
SyntaxParser.
This permits changing the syntax definition syntax if necessary by writing
either a subclass of SyntaxParser or changing the parser store for small
changes or writing a syntax definition file.
To facilitate flexibility in finding the properties from the property names,
two new classes – the
Inspector and
InspectorMill
– are used.
The inspector knows how to create a property for a specific bean class.
The inspector mill knows the inspector for a given class.
The tree of java beans and other objects is mirrored by a tree of inspectors
created while parsing the syntax definition file.
Because inspectors cannot be used in the parsing process,
the creation of a parser from the syntax definition is done in two steps:
- Parsing the text and storing the results in a
ParserBean tree.
The name of the property and not the property is stored in the parser bean.
- Invoking recursively the
toParser()
method, creating properties from the property names.
This requires a parser bean for every parser.
Patterns
Composite Pattern
The composite pattern is used several times within japaki.
It consists of an interface, of which the implementing classes can have
zero to many instances of the interface, so that a tree is built.
The central method takes a data container as argument that is shared among
all members of the tree.
package
| data container
| interface
|
text
| ParseReader ParseWriter
| Parser
|
self
| InspectorMill
| Inspector
|
self
| Inspector
| ParserBean
|