[
https://issues.apache.org/jira/browse/ISIS-369?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Dan Haywood updated ISIS-369:
-----------------------------
Description:
>From our website (http://isis.apache.org):
Apache Isis™ software is a framework for rapidly developing domain-driven apps
in Java. Write your business logic in entities, domain services and
repositories, and the framework dynamically generates a representation of that
domain model as a webapp or a RESTful API. Use for prototyping or production.
~~~
Isis works by building a metamodel from the domain object models, where these
follow a number of straightforward programming conventions (basically, pojos +
some annotations, see our cheat sheet
[http://isis.apache.org/getting-started/cheat-sheet.html]).
A discussion that's we've had on the mailing list a few times is to support a
DSL tailored to these conventions, that would compile down to the same bytecode.
A good candidate technology, we suspect, is Eclipse's XText
[http://www.eclipse.org/Xtext/] or, perhaps, Eclipse XTend
[http://eclipse.org/xtend/]
And below is a sketch of what that DSL might look like.
NB: UPDATED 6-sep-2013
For entities:
@... // Isis and JDO annotations here
entity Customer {
...
inject ProductRepository products;
inject OrderRepository orders;
}
where:
- the products, orders imply an instance variable and a setter to allow
services to be injected into
- DomainObjectContainer container is provided automatically as a field
For entity properties:
entity Customer {
@ ... // annotations here
property String firstName {
get;
set;
modify;
clear;
default;
choices;
hide;
disable;
validate;
}
}
where
- property is a keyword
- String firstName
- implies the instance variable and the getter
- annotations can be specified, apply to the getter
- get;
- is mandatory
- set;
- is optional,
- *** NB: for XText, if omitted, then the getter should be considered as
business logic, not structural.
- modify;
- is optional
- if present, implies the modifyXxx(String value) method
- clear;
- is optional
- if present, implies the void clearXxx() method
- default;
- is optional
- if present, implies the String defaultXxx() method
- choices;
- is optional
- if present, implies the List<String> choicesXxx() method
- hide;
- is optional
- if present, implies the boolean hideXxx() method
- disable;
- is optional
- if present, implies the String disableXxx() method
- validate;
- is optional
- if present, implies the String validateXxx(String value) method
similarly for entity collections:
entity Customer {
@ ... // annotations here
collection List<Order> orders {
get;
set;
addTo;
removeFrom;
hide;
disable;
validateAddTo;
validateRemoveFrom;
}
}
where
- collection is a keyword
- get;
- is mandatory
- set;
- is optional,
- *** NB: for XText, if omitted, then the getter should be considered as
business logic, not structural.
- addTo;
- is optional
- if present ,implies void addTo(Order o) { }
- removeFrom;
- is optional
- if present ,implies void removeFrom(Order o) { }
- hide;
- as properties
- disable;
- as properties
- validateAddTo;
- is optional
- if present ,implies String validateAddToXxx(Order o);
- validateRemoveFrom;
- is optional
- if present ,implies String validateRemoveFromXxx(Order o);
and similarly for entity actions:
entity Customer {
@... // annotations here
action Order placeOrder {
param Product product {
default;
choices;
autoComplete;
validate;
},
param int quantity {
default;
choices;
autoComplete;
validate;
},
param String description {
default;
choices;
autoComplete;
validate;
}
}
hide;
disable;
validate;
}
}
where
- the name of the parameter would imply @Named(...)
- param's default:
- is optional
- corresponds to: Product default0PlaceOrder() { ... }
or: int default1PlaceOrder() { ... }
or: String default2PlaceOrder() { ... }
- param's choices
- is optional
- corresponds to: Collection<Product> default0PlaceOrder() { ... }
or: Collection<Integer> choices1PlaceOrder(Product
p) { ... }
or: Collection<String> choices2PlaceOrder(Product
p, int quantity) { ... }
- note how the Nth method has N-1 params
- ALSO: cannot have both choices and autoComplete
- param's autoComplete
- is optional
- corresponds to Collection<Product> autoComplete0PlaceOrder(String search) {
... }
or: Collection<Integer>
autoComplete1PlaceOrder(Product p, String search) { ... }
or: Collection<String>
autoComplete2PlaceOrder(Product p, int quantity, String search) { ... }
- note how the Nth method has N-1 params + search arg
- ALSO: cannot have both choices and autoComplete
validate for the parameters apply to that parameter
- is optional
- corresponds to String validate0PlaceOrder(Product p) { ... }
or: String validate1PlaceOrder(int quantity) { ...
}
or: String validate2PlaceOrder(String search) { ...
}
- hide
- is optional
- corresponds to boolean hidePlaceOrder() { ... }
- disable
- is optional
- corresponds to String disablePlaceOrder() { ... }
- validate (at action level)
- corresponds to validateXxx(...)
- to validate the set of arguments rather than an individual parameter
~~~~~~~~~~~~
THIS STUFF OUT OF SCOPE/NOT NECESSARY
For values:
value FractionalNumber {
int numerator;
int denominator;
}
is basically the same as Lombok @Data
requires information in @ValueSemanticsProvider to be specified (somehow, not
sure exactly how)
~~~~~~~~~~~~
THIS STUFF OUT OF SCOPE/NOT NECESSARY
For services/repositories:
service ProductRepository {
}
where:
- any services are injected into as for entities
- DomainObjectContainer container is provided for free, again as for entities
- actions as for entities
- properties and collections are disallowed
was:
>From our website (http://isis.apache.org):
Apache Isis™ software is a framework for rapidly developing domain-driven apps
in Java. Write your business logic in entities, domain services and
repositories, and the framework dynamically generates a representation of that
domain model as a webapp or a RESTful API. Use for prototyping or production.
~~~
Isis works by building a metamodel from the domain object models, where these
follow a number of straightforward programming conventions (basically, pojos +
some annotations, see our cheat sheet
[http://isis.apache.org/getting-started/cheat-sheet.html]).
A discussion that's we've had on the mailing list a few times is to support a
DSL tailored to these conventions, that would compile down to the same bytecode.
A good candidate technology, we suspect, is Eclipse's XText
[http://www.eclipse.org/Xtext/] or, perhaps, Eclipse XTend
[http://eclipse.org/xtend/]
And below is a sketch of what that DSL might look like.
For entities:
@... // annotations here
entity Customer {
...
ProductRepository products;
OrderRepository orders;
}
where:
- the products, orders imply an instance variable and a setter to allow
services to be injected into
- DomainObjectContainer container is provided automatically as a field
For entity properties:
entity Customer {
@ ... // annotations here
property String firstName {
set;
modify { ... }
clear { }
default { ... }
choices { ... }
hide { ... }
disable { ... }
validate { ... }
}
}
where
- property is a keyword
- String firstName
- implies the instance variable and the getter
- annotations can be specified, apply to the getter
- set;
- is optional,
- if present implies the setter (and so is a non-derived property)
- syntax borrowed from C#
- modify { ... }
- is optional
- if present, implies the modifyXxx(String value) method
- 'value' would be an implicitly available locally scoped parameter
- clear { ... }
- is optional
- if present, implies the void clearXxx() method
- default { ... }
- is optional
- if present, implies the String defaultXxx() method
- choices { ... }
- is optional
- if present, implies the List<String> choicesXxx() method
- hide { ... }
- is optional
- if present, implies the boolean clearXxx() method
- disable { ... }
- is optional
- if present, implies the String disableXxx() method
- validate { ... }
- is optional
- if present, implies the String validateXxx(String value) method
- 'value' would be an implicitly available locally scoped parameter
similarly for entity collections:
entity Customer {
@ ... // annotations here
collection List<Order> orders {
addTo { ... }
removeFrom { }
hide { ... }
disable { ... }
validateAddTo { ... }
validateRemoveFrom { ... }
}
}
where
- collection is a keyword
- otherwise similarly as properties
and similarly for entity actions:
entity Customer {
@... // annotations here
action Order placeOrder(
Product product {
default { }
choices { }
validate { }
},
int quantity {
default { }
choices { }
validate { }
}
) {
body { ... }
hide { ... }
disable { ... }
validate { ... }
}
}
where
- the name of the parameter would imply @Named(...)
- the default, choices, validate for the parameters apply to that parameter
- imply corresponding defaultNXxx(), choicesNXxx, validateNXxx()
- where N = parameter number
- body { ... }
- is the action body, with the parameters defined
- hide, disable
- similarly
- validate (at action level)
- corresponds to validateXxx(...)
- to validate the set of arguments rather than an individual parameter
Any members that do not follow the above rules are just copied over "as-is"
into Java.
~~~~~~~~~~~~
For values:
value FractionalNumber {
int numerator;
int denominator;
}
is basically the same as Lombok @Data
requires information in @ValueSemanticsProvider to be specified (somehow, not
sure exactly how)
~~~~~~~~~~~~
For services/repositories:
service ProductRepository {
}
where:
- any services are injected into as for entities
- DomainObjectContainer container is provided for free, again as for entities
- actions as for entities
- properties and collections are disallowed
> [Mentored?] A domain-specific language aligned with the Apache Isis
> programming conventions.
> --------------------------------------------------------------------------------------------
>
> Key: ISIS-369
> URL: https://issues.apache.org/jira/browse/ISIS-369
> Project: Isis
> Issue Type: New Feature
> Reporter: Dan Haywood
> Labels: ddd, domain-driven-design, dsl, framework, gsoc, java,
> mentor, mentoring, nakedobjects
>
> From our website (http://isis.apache.org):
> Apache Isis™ software is a framework for rapidly developing domain-driven
> apps in Java. Write your business logic in entities, domain services and
> repositories, and the framework dynamically generates a representation of
> that domain model as a webapp or a RESTful API. Use for prototyping or
> production.
> ~~~
> Isis works by building a metamodel from the domain object models, where these
> follow a number of straightforward programming conventions (basically, pojos
> + some annotations, see our cheat sheet
> [http://isis.apache.org/getting-started/cheat-sheet.html]).
> A discussion that's we've had on the mailing list a few times is to support a
> DSL tailored to these conventions, that would compile down to the same
> bytecode.
> A good candidate technology, we suspect, is Eclipse's XText
> [http://www.eclipse.org/Xtext/] or, perhaps, Eclipse XTend
> [http://eclipse.org/xtend/]
> And below is a sketch of what that DSL might look like.
> NB: UPDATED 6-sep-2013
> For entities:
> @... // Isis and JDO annotations here
> entity Customer {
> ...
>
> inject ProductRepository products;
> inject OrderRepository orders;
> }
> where:
> - the products, orders imply an instance variable and a setter to allow
> services to be injected into
> - DomainObjectContainer container is provided automatically as a field
> For entity properties:
> entity Customer {
> @ ... // annotations here
> property String firstName {
> get;
> set;
> modify;
> clear;
> default;
> choices;
> hide;
> disable;
> validate;
> }
> }
> where
> - property is a keyword
> - String firstName
> - implies the instance variable and the getter
> - annotations can be specified, apply to the getter
> - get;
> - is mandatory
> - set;
> - is optional,
> - *** NB: for XText, if omitted, then the getter should be considered as
> business logic, not structural.
> - modify;
> - is optional
> - if present, implies the modifyXxx(String value) method
> - clear;
> - is optional
> - if present, implies the void clearXxx() method
> - default;
> - is optional
> - if present, implies the String defaultXxx() method
> - choices;
> - is optional
> - if present, implies the List<String> choicesXxx() method
> - hide;
> - is optional
> - if present, implies the boolean hideXxx() method
> - disable;
> - is optional
> - if present, implies the String disableXxx() method
> - validate;
> - is optional
> - if present, implies the String validateXxx(String value) method
>
> similarly for entity collections:
> entity Customer {
> @ ... // annotations here
> collection List<Order> orders {
> get;
> set;
> addTo;
> removeFrom;
> hide;
> disable;
> validateAddTo;
> validateRemoveFrom;
> }
> }
> where
> - collection is a keyword
> - get;
> - is mandatory
> - set;
> - is optional,
> - *** NB: for XText, if omitted, then the getter should be considered as
> business logic, not structural.
> - addTo;
> - is optional
> - if present ,implies void addTo(Order o) { }
> - removeFrom;
> - is optional
> - if present ,implies void removeFrom(Order o) { }
> - hide;
> - as properties
> - disable;
> - as properties
> - validateAddTo;
> - is optional
> - if present ,implies String validateAddToXxx(Order o);
> - validateRemoveFrom;
> - is optional
> - if present ,implies String validateRemoveFromXxx(Order o);
>
> and similarly for entity actions:
> entity Customer {
> @... // annotations here
> action Order placeOrder {
> param Product product {
> default;
> choices;
> autoComplete;
> validate;
> },
> param int quantity {
> default;
> choices;
> autoComplete;
> validate;
> },
> param String description {
> default;
> choices;
> autoComplete;
> validate;
> }
> }
> hide;
> disable;
> validate;
> }
> }
> where
> - the name of the parameter would imply @Named(...)
> - param's default:
> - is optional
> - corresponds to: Product default0PlaceOrder() { ... }
> or: int default1PlaceOrder() { ... }
> or: String default2PlaceOrder() { ... }
> - param's choices
> - is optional
> - corresponds to: Collection<Product> default0PlaceOrder() { ... }
> or: Collection<Integer>
> choices1PlaceOrder(Product p) { ... }
> or: Collection<String> choices2PlaceOrder(Product
> p, int quantity) { ... }
> - note how the Nth method has N-1 params
> - ALSO: cannot have both choices and autoComplete
> - param's autoComplete
> - is optional
> - corresponds to Collection<Product> autoComplete0PlaceOrder(String search)
> { ... }
> or: Collection<Integer>
> autoComplete1PlaceOrder(Product p, String search) { ... }
> or: Collection<String>
> autoComplete2PlaceOrder(Product p, int quantity, String search) { ... }
>
> - note how the Nth method has N-1 params + search arg
> - ALSO: cannot have both choices and autoComplete
> validate for the parameters apply to that parameter
> - is optional
> - corresponds to String validate0PlaceOrder(Product p) { ... }
> or: String validate1PlaceOrder(int quantity) {
> ... }
> or: String validate2PlaceOrder(String search) {
> ... }
> - hide
> - is optional
> - corresponds to boolean hidePlaceOrder() { ... }
> - disable
> - is optional
> - corresponds to String disablePlaceOrder() { ... }
> - validate (at action level)
> - corresponds to validateXxx(...)
> - to validate the set of arguments rather than an individual parameter
>
>
> ~~~~~~~~~~~~
> THIS STUFF OUT OF SCOPE/NOT NECESSARY
> For values:
> value FractionalNumber {
> int numerator;
> int denominator;
> }
> is basically the same as Lombok @Data
> requires information in @ValueSemanticsProvider to be specified (somehow, not
> sure exactly how)
> ~~~~~~~~~~~~
> THIS STUFF OUT OF SCOPE/NOT NECESSARY
> For services/repositories:
> service ProductRepository {
> }
> where:
> - any services are injected into as for entities
> - DomainObjectContainer container is provided for free, again as for entities
> - actions as for entities
> - properties and collections are disallowed
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira