Running Bear Manual

Don Batory
Department of Computer Science
The University of Texas at Austin
Austin, TX, USA

Running Bear (RB) is a MDELite's Model-to-Text (M2T) tool.    It is a tiny Java file that offers 14 static methods, of which the most important the two in green rows.

Return TypeMethodUsage
voidRBSetup(Marquee2Arguments mark, String... args)Open the command-line specified database and output file
String
getDatabaseInputFile()
return the name of the database file
String
getOutputFileName()
return the name of the RB output file
DB
getDB()
return the DB object produced by reading the database

voidopenOut(String filename)direct RB output to the given file
voidopenOut(PrintStream o)direct RB output to the given PrintStream
voidcloseOut()close the opened RB PrintStream or file
PrintStream
getOut()
return the PrintStream object of RB

StringgetDatabase()return the filename of the current database
StringgetOutputFileName()return the file name of the current output file
voidp(String format, Object... args)print(format,arguments) no line eject
voidl(String format, Object... args)println(format, arguments) with line eject
void
l()
print blank line
void
l(int n)
print n blank lines

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 the 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 MDLUtilities.Marquee1In_1Out;
import MDLUtilities.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
Marquee1In_1Out mark = new Marquee1In_1Out(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 ... this is where the heavy lift occurs

}

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 argument true, separate .java files are produced per class.  That's about it.