2. Specification Language
“A specification language … used during systems analysis, requirement
analysis and system design to describe a system at a much higher level
than a programming language…” -Wikipedia
Spec Languages examples: CASL, VDM, Z, Alloy, UML, etc.
3. Native Code Generating
Cross-platform translation
Specification
DSL
AST
Android Native
Project
iOS Native
Project
Requirements
Component
Model
Data
structures
4. Native Code Generating (contd.)
• Requirements – functional and non-functional, use-cases, user-stories,
feature-lists, business rules, etc.
• Component Model – splitting the application area into a set of components
with precise interfaces and behavior:
Widgets
ContentProvider, Entities
Services, BroadcastReceivers
NotificationService
GPS, GMap
Camera, Audio, Sensors
• Data structures – data entities and bindings between entities and
components.
• Specification DSL is a Ubiquitous language of the problem domain.
5. Domain Specific Language (DSL)
Overview
“Domain modeling (or domain analysis) involves the identification of all
the major components of the domain and how they collaborate.”
– DSLs in Action, D.Ghosh
The problem domain is the processes, entities and business rules that
are part of the analysis.
The solution domain is the implementation of problem domain in
terms of components with precisely defined behavior.
6. Scala as a host language of a DSL
Scala is a good choice to be a host language of the specification DSL
since it supports a lot of approaches makes it DSL friendly:
• Operators overriding
• Implicit conversions
• Infix notation to avoid parenthesis
• High-order functions, currying
• Meta-programming (macroses)
• Statically typed
7. Meta Model: Containers and
Components
An application specified in terms of components and connections
between components. Each component could contain inner
components (container).
A connection indicates either data flow or events-handling
relation between components.
GuiContainer is an example of a group of widgets that translates
to UI functionality. A connector between two Gui Containers
means that there is for instance a navigation event from one to
another.
8. Meta Model: Data Binding and Events
Handling
The DSL supports several kinds of Data Binding relations
between components:
Events-handling allows to add behavior to components, several
groups of events supported (navigation, persistence, messaging,
etc.):
gui1.listView1.onClick >~ gui2.doActivate
gui1.pane1.onUpdate >~ dbPrv.doUpdate
gui1 <~ dbPrv
Read-only binding Write-only binding Bidirectional binding
target <= source source >= target comp1 <=> comp2
9. Sample App
val mainActivity = GuiContainer(
EditText(‘address), EditText(‘longitude), EditText(‘latitude)
)
val db = DbProvider {
val coordinates = Entity {
val address = Item
val longitude = Item
val latitude = Item
}
}
mainActivity <~> db
mainActivity <=> db.coordinates
11. Component Open API
Simplified API that each component conforms to:
trait Component {
val owner: Component
def inners: Set[Component]
def events: Set[Event]
def handlers: Set[Handler]
def bound: Option[Component]
def +=(comp: Component): this.type
def <~(comp: Component): this.type
def ~>(comp: Component): this.type
def <~>(comp: Component): this.type
def <=(comp: Component): this.type
def >=(comp: Component): this.type
def <=>(comp: Component): this.type
def generate(code: Code): Unit
}
12. Component Open API (contd.)
It’s a component’s responsibility to initialize owner field of each
inner component. events and handlers returns respective lists of
instances and bound reflects a data binding relation added.
+=-operator appends inner components, <~, >~, <~> manage
even-handling capabilities and <=, >=, <=> control data bindings.
Overridden method generate provides native code generating –
business-logic specifics, features implementation using dynamic
template engine.
13. Component-based Open API (contd.)
Embedding of business logic and customization of the component’s behavior should be applied per each particular component type:
generate(app: Code): Unit = this match {
case root: App =>
root.generate(app)
root.inners.foreach(_.generate(app))
~app
case gui: GuiContainer =>
val activity = Public::Class(gui.id, AndroidAppActivity)
gui.generate(activity)
gui.inners.foreach(_.generate(activity))
case dbPrv: ContentProvider =>
val provider = Public::Class(dbPrv.id, AndroidContentContentProvider)
dbPrv.generate(provider)
dbPrv.inners.foreach(_.generate(provider))
}
14. Java CodeGen DSL
Code Generation DSL (Codegen DSL or just Codegen) is a meta-programming framework that allows generating
of Java-classes based on dynamic composition of fragments of code into methods and classes.
Fragments of code are templates contain expressions within ${} that calculated while using Scala string
interpolation process. Code fragment trait has a ~-operator that evaluates a template. E.g. fragment
~$"""
super.onCreate(savedInstanceState);
setContentView(R.layout.${activity.sName});
"""
will generate Java-code (activity.sName is “activity1”):
super.onCreate(savedInstanceState);
setContentView(R.layout.activity1);
15. Java CodeGen DSL (contd.)
Available at https://github.com/alex-evseenko/codegen
Supports API to dynamically add templates and then generate code:
val activity = Public::Class(app.guiPackage, 'MyActivity, AndroidAppActivity)
val onCreate =
Override::Public::Method('onCreate, 'savedInstanceState->AndroidOsBundle, JavaVoid)(
$"""
super.onCreate(savedInstanceState);
setContentView(R.layout.${activity.sName});
""")
activity += onCreate
~activity
16. Web-platform
To expose the DSL functionality to end-users simple web-app is
available at http://adaldev.com
It consists from Apps Repository, Builder and Target project page to
create an app, translate it to native Android project and then build
binary module.
17. Advantages and Disadvantages
Clearly defined borders of components
Extendable and customizable components
Automation Integral Testing
Produce readable native code
Cross-platform and multi-versioning
Meta-programming is difficult to integrate with IDE
Supporting of business logic
Reverse engineering from native code to meta-model is difficult