Running Bear
Manual
Don BatoryDepartment of Computer ScienceThe University of Texas at AustinAustin, TX, USA
Running Bear (RB) is a MDELite's Model-to-Text (M2T) tool. It is a tiny Java file that offers 8 static methods, of which the most important are the last two.
Return Type | Method | Usage |
void | RBSetup(Marquee2Arguments mark, String... args) | Open the command-line specified database and output file |
void | openOut(String filename) | direct RB output to the given file |
void | openOut(PrintStream o) | direct RB output to the given PrintStream |
void | closeOut() | close the opened RB PrintStream or file |
String | getDatabase() | return the filename of the current database |
String | getOutputFileName() | return the file name of the current output file |
void | p(String format, Object... args) | print(format,arguments) no line eject |
void | l(String format, Object... args) | printline(format, arguments) with line ej |
Outline of an RB Program
An RB program implements a M2T tool. It maps an MDELite database to a text file (which could be a java file, html file, or whatever). The command-line of an RB program is standardized:
> java myRBProgram X.Y.pl [outputfile]
That is, an RB program takes a database file as input (X is the name of the file, Y is the name of its schema, pl designates a MDELite database), and optionally the name of an output file. As we'll see shortly, the output file name is computed from the input file name, and the computation is specified in the RBSetup method. For debugging purposes, I specify an explicit output file (say "out.txt") to avoid output file proliferation. The basic template of a RB program is:
import MDELite.Marquee2Arguments;
import MDELite.RunningBear;
import PrologDB.Table;
import PrologDB.Tuple;
public class demo extends RunningBear {
static Table cls, fld;
public static void main(String... args) {
// Step 1: standard marquee processing
Marquee2Arguments mark = new Marquee2Arguments(demo.class, ".classes.pl", ".txt", args);
RBSetup(mark, args); // opens "X.classes.pl" database, as specified on the command line
// variable db is the opened database
// file "X.java" is opened (or whatever command-line output is specified
// Step 2: open tables of database
cls = db.getTableEH("class");
fld = db.getTableEH("field");
// Step 3: "generate" code ...
}
Simple Example
Here is a simple database:
dbase(classes,[class,field]).
table(class,[cid,name,superName]).
class(c0,entity,null).
class(c1,student,entity).
class(c2,course,entity).
table(field,[fid,name,type,cid]).
field(f0,name,String,c0).
field(f1,UTEID,String,c1).
field(f2,profName,String,c2).
Here is the desired output:
class entity {
String name;
}
class student extends entity {
String UTEID;
}
class course extends entity {
String profName;
}
The extra code that is added to the template above to generate this is:
cls.forEach(c->genClass(c,false));
// Step 4: done
}
static void genClass(Tuple c, boolean separateFile) {
// Step 1: print the class header
String sup = c.get("superName");
String xtends = (!sup.equals("null"))?"extends "+sup:"";
if (separateFile) {
openOut(c.get("name")+".java");
}
l("class %s %s {", c.get("name"), xtends);
// Step 2: compute table of c's fields
Table cfields = c.rightSemiJoin("cid",fld,"cid");
// Step 3: declare all fields and their types
cfields.forEach(f-> l(" %s %s;", f.get("type"), f.get("name")));
// Step 4: print the class footer
l("}");
l(1);
if (separateFile) {
closeOut();
}
}
By invoking method genclass with true, separate .java files will be produced per class. That's about it.