There are a lot of cases where the implementation of those operations is the
same, and Isis could avoid to explicitly implement it.
For entities, normally is something like:
public void delete(Entity entity) {
this.getContainer().remove(entity);
this.getContainer().flush();
}
Perhaps flush can be optional, perhaps if implemented directly on the entity
there shouldn't be any params, but base code remains the same.
If all entities have a common descendant, it can be implemented on a generic
service that accepts one instance as a param. But perhaps that "basic"
operation could be implemented directly by the framework.
Its deletion could be vetoed by means of the Isis "removing()" method, for
example, and also by means of the EventServiceBus.
Perhaps a default implementation on an Isis service could be given?
But there's another case that it's "polluting" our domain entities and we
haven't achieve a standard way to implement it, despite I think it's possible.
For nearly each collection, we need:
- an "addXXX" action (that normally accepts one existing instance of the
collection elements - i.e., a Price List adding existing Items -).
- sometimes, a "createXXX" action (that create an instance and after that calls
addXXX; think of an Aggregated Root creating all contained Entity instances -
i.e., an Order creating new Line Items -).
- a "deleteXXX" action (that mainly consists of a
"getCollection.remove(entity)"; if the collection was annotated with
dependentElement="true", the instance will removed AND deleted by DataNucleus
after executing it).
From those three, createXXX need custom business logic to work and cannot be
easily generalized (createXXX needs required fields of the entity created).
But addXXX and deleteXXX, when available, have a quite generic implementation:
@PersistenceCapable
@Inheritance(strategy = InheritanceStrategy.NEW_TABLE)
@Discriminator(value = "BusinessService")
public class InformationSystem extends ApplicationComponent {
// {{ UsesSoftwareServices (Collection)
@Persistent(mappedBy = "usedByInformationSystem", dependentElement =
"false")
private SortedSet<SoftwareService> usesSoftwareServices = new
TreeSet<SoftwareService>();
@MemberOrder(sequence = "710")
public SortedSet<SoftwareService> getUsesSoftwareServices() {
return this.usesSoftwareServices;
}
public void setUsesSoftwareServices(final SortedSet<SoftwareService>
usesSoftwareServices) {
this.usesSoftwareServices = usesSoftwareServices;
}
// }}
// {{ addSoftwareService (action)
@ActionSemantics(Of.IDEMPOTENT)
@MemberOrder(name = "usesSoftwareServices", sequence = "010")
public void addSoftwareService(@XMSBulkParam @Named("Software Service")
final SoftwareService softwareService) {
this.getUsesSoftwareServices().add(softwareService);
this.getContainer().flush();
}
// }}
// {{ deleteFromUsesSoftwareServices (action)
@ActionSemantics(Of.IDEMPOTENT)
@MemberOrder(name = "usesSoftwareServices", sequence = "020")
public void deleteFromUsesSoftwareServices(@XMSBulkParam @Named("Servicio
de Software") final SoftwareService softwareService) {
this.getUsesSoftwareServices().remove(softwareService);
this.getContainer().flush();
}
// }}
...
}
Couldn't they be provided by default also by Isis?
For example, by annotating the collection with something similar to:
@Collection(addAction="Add Software Service", deleteAction="Remove Software
Service")
Which would reduced the code to:
@PersistenceCapable
@Inheritance(strategy = InheritanceStrategy.NEW_TABLE)
@Discriminator(value = "BusinessService")
public class InformationSystem extends ApplicationComponent {
// {{ UsesSoftwareServices (Collection)
@Persistent(mappedBy = "usedByInformationSystem", dependentElement =
"false")
private SortedSet<SoftwareService> usesSoftwareServices = new
TreeSet<SoftwareService>();
@Collection(addMethodName="Add Software Service", deleteAction="Remove
Software Service")
@MemberOrder(sequence = "710")
public SortedSet<SoftwareService> getUsesSoftwareServices() {
return this.usesSoftwareServices;
}
public void setUsesSoftwareServices(final SortedSet<SoftwareService>
usesSoftwareServices) {
this.usesSoftwareServices = usesSoftwareServices;
}
// }}
...
}
If I remember it well, Martin suggested once something similar for collections.
Perhaps am I missing anything not allowing such generic implementations being
supported by Isis ?
Regards,
Oscar
Óscar Bou Bou
Responsable de Producto
Auditor Jefe de Certificación ISO 27001 en BSI
CISA, CRISC, APMG ISO 20000, ITIL-F
902 900 231 / 620 267 520
http://www.twitter.com/oscarbou <http://www.twitter.com/oscarbou>
http://es.linkedin.com/in/oscarbou <http://es.linkedin.com/in/oscarbou>
http://www.GesConsultor.com <http://www.gesconsultor.com/>
Este mensaje y los ficheros anexos son confidenciales. Los mismos contienen
información reservada que no puede ser difundida. Si usted ha recibido este
correo por error, tenga la amabilidad de eliminarlo de su sistema y avisar al
remitente mediante reenvío a su dirección electrónica; no deberá copiar el
mensaje ni divulgar su contenido a ninguna persona.
Su dirección de correo electrónico junto a sus datos personales constan en un
fichero titularidad de Gesdatos Software, S.L. cuya finalidad es la de mantener
el contacto con Ud. Si quiere saber de qué información disponemos de Ud.,
modificarla, y en su caso, cancelarla, puede hacerlo enviando un escrito al
efecto, acompañado de una fotocopia de su D.N.I. a la siguiente dirección:
Gesdatos Software, S.L. , Paseo de la Castellana, 153 bajo - 28046 (Madrid), y
Avda. Cortes Valencianas num. 50, 1ºC - 46015 (Valencia). Asimismo, es su
responsabilidad comprobar que este mensaje o sus archivos adjuntos no contengan
virus informáticos, y en caso que los tuvieran eliminarlos.