10.1. Compiling DNAL Source
The DNALCompiler class compiles DNAL source from a file, input stream, or string.
public interface DNALCompiler {
CompilerOptions getCompilerOptions();
void registryRuleFactory(RuleFactory factory);
DataSet compile(String path);
DataSet compile(String path, OuputGenerator visitor);
DataSet compile(InputStream stream);
DataSet compile(InputStream stream, OutputGenerator visitor);
DataSet compileString(String input);
DataSet compileString(String input, OuputGenerator visitor);
List getErrors();
void clearErrors();
}
After checking the input source is valid DNAL, the compiler builds an in-memory representation of the types and values. Each value is then validated using the validation rules defined for its type. If compilation is successful, a DataSet is returned. Also, if an OuputGenerator was supplied, then the types and/or values are rendered to it.
If any errors occur, the compiler stops and returns NULL. Use getErrors to retrieve the errors. The compiler will not produce any output if there are errors.
DNALCompiler is single use only. Create a new instance for each compile.
10.2 DValue
Values in a DataSet are represented by immutable DValue objects. DValue is a thin-wrapper around a Java object such as a Boolean or String.
public interface DValue {
int asInt();
double asNumber();
long asLong();
String asString();
boolean asBoolean();
Date asDate();
List asList();
Map asMap();
DStructHelper asStruct();
//..
10.3 DataSet
A DataSet is an set of DNAL types and values. It is guaranteed to be 100% valid. That is, its values have passed their validation rules. Also, if a field is not marked optional, then it is guaranteed to be not NULL.
public interface DataSet {
DValue getValue(String varName);
T getAsBean(String varName, Class clazz);
void registerBeanLoader(BeanLoader loader);
Transaction createTransaction();
DataSet cloneEmptyDataSet();
//...
}
Each value defined by a let statement in the DNAL source is called a top-level value and can be retrieved by calling getValue. It returns a DValue object which has methods to retrieve the value as a Java int, boolean, String, List, etc.
A BeanLoader converts a DVAL struct value into a Java bean. Use registerBeanLoader to register the bean loader, and then getAsBean to get the value as a fully-populated bean.
Note. A reflection-based loader is also available. DNALLoader can load values into a DataSet from Java beans.
10.3.1 Are DataSets immutable?
The DataSet interface does not have any methods for modifying its data. Its contents are immutable types (DType) and immutable values (DValue). Does this mean that DataSet is immutable? Yes, DNAL is not an execution language; it is a data language. It represents values frozen in time. Also, immutable values have many advantages in programming, such as thread safety.
However, there are times when modifying a dataset can be useful, and the DVAL API provides a controlled mechanism to do this. It will be discussed in Transactions below.
10.3.2 Cloning a DataSet
createEmptyDataSet is an efficient way to create a copy of a dataset. It contains the types of the parent dataset, but no values. This can be useful in conjunction with transactions (see Transactions below).
10.4 Transactions
public interface Transaction {
void add(String name, DValue dval);
boolean commit();
//...
The add method adds a new top-level value. It is equivalent to a let statement in DNAL. The values in the transaction are stored inside the Transaction until the commit method is called. commit validates all the values according the the validation rules of their DNAL type. Committing a transaction, like a database transaction, is all or nothing. Either all the values in the Transaction get added to the DataSet or none of them do.
10.4.1 Using DNAL for Data Validation
10.5 Custom Rules
Custom rules are implemented by Java classes that implement the NRule interface. Register the rule with the DNALCompiler registerRuleFactory method.