340 likes | 499 Views
Bottom Up Creation of a DSL Using JSON Templates An workbench with a novel editor http://ltiwww.epfl.ch/BUDE. Template Based Development Environment. Specification object. Source. Generation. Enhancement. DSL compiler. Template. Template. Template. Javascript object. Enhanced object.
E N D
Bottom Up Creation of a DSL Using JSON TemplatesAn workbench with a novel editorhttp://ltiwww.epfl.ch/BUDE
Template Based Development Environment Specification object Source Generation Enhancement DSL compiler Template Template Template Javascript object Enhanced object Editor / generator Description file Expansion JSON Generated files Generated files
The JSON Objects and the Templates(Introduction) JSON expansion Templates Specification object Description file
Principle of the Expansion of the JSON Templates! JSON description Template a: [ {item: "carots", price: 12}, {item: "onions", price: 20}, {item: "spinachs", price: 15} ] {.repeated section a} The price of {item} is {price} RS {.end} Expansion The price of carots is 12 RS The price of onions is 20 RS The price of spinachs is 15 RS Resulting page http://json.org
Template Commands {name} {.section name} {.or} {.end} {.repeated section name}{.or} {.alternates with} {.end} {.include "filename"}
JSON (Javascript) Objects are recursive { create : { id : "customer", inputVar : "customerName", attributes : [{ intAttribute : { varName : "number" } } ] } [ . . . ] array } { . . . }object
Empty Attribute: conditional generation { create : { id : "customer", selector: { }, inVar : "cName" } } {.section selector} String {inVar}; {.end} { create : { selector: { id : "customer", inVar : "cName" } } } // same code generated // with both objects
Ordered Sequence attributes : [ { stringAttribute: { varName : "name" } }, { intAttribute: { varName : "number" } } ] {.repeated section attributes} {.section intAttribute} int {varName} = 0; {.end} {.section stringAttribute} String {varName} = ""; {.end} {.end} Expansion public class Customer { String name = ""; int number = 0; }
Other Example dataTables : [ { id : "customer", attributes : [ { stringAttribute: { varName : "name", finder: { } } }, { intAttribute: { varName : "number" } } ], relationships : [ { OneToMany : { to : "confirmedOrder" } } ] } Result of the expansion public class Customer { String name = ""; int number = 0; public static findByName(String name) { query = "select * from customer where name='"+name+"'"; result = execute(query); } @OneToMany public Collection confirmedOrder; }
Generation of an Application (requires a set of files) { dataTables: [ { id : "customer", inpVar : "custName" } ] } {.section create} class {Id} { String {inpVar} } {.end} File description foreach dataTables expand "dataTemplate.java" to "src/data/"+Id+".java" for whole expand "taskTemplate.java" to "src/data/Task.java" Expansion aaa bbb abcd ccc ddd aaa bbb abcd ccc ddd aaa bbb abcd ccc ddd class Customer { String customerName; }
Computation of the Object Arguments Specification object Enhancement Template Template Templates Extended specification object Description file Expansion Computations are made in the specification object, not in the templates Generated files Generated files
Computation of Object Arguments { create : { id : "customer", Id : "Customer", inputVar : "customerName", InputVar : "CustomerName", attributes : [{ intAttribute : { varName : "number" }, _index : "0" } ], myObject : "CUSTOMER_NAME" } } uppercase {equals (id, inputVar)} { create : { id : "customer", inputVar : "customerName", #attributes : "dataTables[customer].attributes", #myObject : "myMethod(inputVar)" }
BUDE: an Eclipse Plugin Double-click: selection of a file
BUDE selection marked if found highlighted if error
Scope of the approach • Intra-file levelduplication of parts such as menus and sub-menus in a GUI • Application levelduplication of files and repetitive components within the files • Architecture levelextension of an application, creation of another application from a set of predefined components
More Examples • Tutorial , tutorial file • Menus and submenus in a GUI (intra-file) • General Ressort (application level) • The DSL compiler itself
2) Menus of a GUI { menus : [{ id : "Files", items : [ { itemId: "Load" }, { itemId: "Save" } ] } , { . . . } ] } private static final long serialVersionUID = 1L; private JPanel jContentPane = null; private JMenuBar GUIMenuBar = null; {.repeated section menus} private JMenu j{id}Menu = null; {.repeated section items} private JMenuItem j{itemId}Item = null; {.end} {.end} Expansion
3) A Workflow: Company General Ressort Task create not Customer name Customer record Customer order (paper) found enter Confirmed order createR Customer part id Part record enter found not create Preconditions (work with A.Wegmann and B.Bajic)
Specification Object { application : { version_id : "memory", memory: { }, database : "test", username : "" }, dataTables : [ { id : "customer", attributes : [ { stringAttribute: { }, varName : "name", finder }, { intAttribute: { }, varName : "number" } ], relationships : [ { OneToMany : { to : "confirmedOrder" } } ] }, { . . . actions : [ { enterAndFind, inputVar : "customerName", #insert : "dataTables[customer]" precondition : [ { stringNotAvailable : "customerPartId" } ] }, { create, inputVar : "customerName", #insert : "dataTables[customer]", transfers : [ { fromAttribute : "customerName", toAttribute : "name" } ], precondition : [ { stringAvailable : "customerName" }, { recordNotAvailable : "customer" } ], #enterAttr : "setSubtract(attributes,\"varName\" ,attributes,\"finder.varName\")" }, { . . .
Specification Object: Continuation roles : [ { id : "secretary", roleActionList : [ { #enterAndFind : "actions[enterAndFind.customer]" }, { #create : "actions[create.customer]" }, { #enterAndFind : "actions[enterAndFind.part]" }, { confirmed : { #dataTables : "dataTables" } } ] }, { id : "engineer", roleActionList : [ { #create : "actions[create.part]" } ] } ]
Architecture enterInputVar.jsp IdRole.jsp createIdRecord.jsp logicServlet.java HomePage.jsp EnterIdData.jsp logicData.java Manager.jsp jump to calls task.java dataTable.java
Description File foreach actions where enterAndFind != null expand "WebContent/Enter.jsptmpl" to "WebContent/Enter"+InputVar+".jsp" foreach actions where createRecord != null expand "WebContent/CreateRecord.jsptmpl" to "WebContent/Create"+Id+".jsp" foreach actions where create != null expand "WebContent/EnterData.jsptmpl" to "WebContent/Enter"+Id+"Data.jsp" for whole expand "WebContent/Manager.jspTmpl" to "WebContent/Manager.jsp" for application, dataTables where JPA!=null expand "JPA/persistence.xmlTmpl" to "src/META-INF/persistence.xml" copyfile "WebContent/web.xml" "WebContent/WEB-INF/web.xml" copyfile "JPA/Manager.java" "src/weblangUtils/Manager.java" copyfile "SQL/DBConnection.java" "src/weblangUtils/DBConnection.java" copydir "lib" "/WebContent/WEB-INF/lib" output directory ".." // relative to the directory of this file uppercase {equals (id, tableName, inputVar, varName, to)} foreach dataTables, application expand application.version_id + "/Customer.java" to "src/data/"+Id+".java" for whole expand application.version_id+"/Task.java" to "src/data/Task.java" for whole expand "business/LogicServlet.java" to "src/business/LogicServlet.java" for whole expand "business/LogicData.java" to "src/business/LogicData.java" foreach roles, actions, dataTables expand "WebContent/SecretaryRole.jsptmpl" to "WebContent/"+Id+"Role.jsp" for whole expand "WebContent/ERP.jsptmpl" to "WebContent/ERP.jsp"
4) DSL : tables dataTable customer { finder string name; int number; OneToMany to confirmedOrder } dataTable part { finder string partId; string grPartInfo; OneToMany to confirmedOrder } dataTable confirmedOrder { string comment; ManyToOne to customer ManyToOne to part } dataTables : [ { id : "customer", attributes : [ { stringAttribute, varName : "name", finder }, { intAttribute, varName : "number" } ], relationships : [ { OneToMany : { to : "confirmedOrder" } } ] }, {
Creation of the DSL Source Specification Object Linear Object AST Compiler DSL Template
Compiler – JavaCC(generated by templates) • { • "attributes" • "{" • ( // guarded object • obj = stringAttributeProd() • { ((JSONObject)obj).names.add(0,"stringAttribute"); • ((JSONObject)obj).objects.add(0,new Highlight()); } • { attributes.put(obj); } • | • obj = intAttributeProd() • { ((JSONObject)obj).names.add(0,"intAttribute"); • ((JSONObject)obj).objects.add(0,new Highlight()); } • { attributes.put(obj); } • )+ • "}" • { return attributes; } • } optimisation of the language
General Ressort DSL: actions and roles actions { enterAndFind { inputVar customerName table customer precondition { stringNotAvailable customerPartId } } enterAndFind { . . . } create { inputVar customerName tableToCreate customer transfers { from customerName to name; } precondition { stringAvailable customerName recordNotAvailable customer } } create { . . . } createRecord { . . . } } roles secretary { enterAndFind customer enterAndFind part create customer createRecord confirmedOrder } roles engineer { create part }
Remarks About the Approach • The description file provides the list of all the kinds of components and defines thus the architecture • The specification object gives the customer's view • The templates implement the platform view
Generation of Web Applications • RAD tools: Eclipse/WTP, Ruby on Rails, Spring Roo, Tutorials (quick start + copy and paste) • Successful former experience with WebLang • A Web application built with our approach and using either SQL, JPA, JSF or PHP from the same object
Conclusions • The approach only uses elementary statements (like if then else or inherit) • No specific library or package required – only (visible) templates • Templates have been pulled out of the RAD tool and transferred into the developer's space • These templates are highly customizable and reusable
Conclusion's Conclusion • Programming languages have been developed layer after layer: Modula, Java, Scala (procedure, object, inheritance, genericity, annotations) • A simple version of DSM can be developed from the JSON templates and make a greater leap forward