Ticket #225 (closed enhancement: fixed)

Opened 6 years ago

Last modified 6 years ago

Rewrite #2 : rewrite template model (+template editor + tags) into a plugin

Reported by: work@… Owned by: work@…
Priority: major Milestone: Should have
Component: Core Functionality Version:
Keywords: Cc:
Hardware: Operating system:
Product: URL:


The generic parts of the study capture wizard to create ajaxified webflows are being rewritten in #183. The other part that is generic enough among dbnp / nmcdsp projects is the form generation of templated entities. This should be rewritten / refactored into a private plugin for the nexus server. Probably the taglib in this plugin should extend the ajax-flow plugin's taglib. Hence, this relies on #183

Change History

comment:1 Changed 6 years ago by work@…

  • Summary changed from Rewrite #2 : rewrite wizard template tags into a private plugin to Rewrite #2 : rewrite template model (+template editor + tags) into a plugin

comment:2 Changed 6 years ago by work@…

  • Created GDT (Grails Domain Templates) plugin version 0.0.1
  • refactored GSCF to use GDT instead (moved all obsolete code out) in r1426


  1. Template owner was originally a SecUser? which is stored in the PostgresSQL database as owner_id (int8). I was setting up Template to work transparently but adding a transient 'owner' and Long owner_id. Overloading the setOwner method should set the owner_id to the id of the owner so we do not need to perform database changes. This would also mean that probably the findByOwner stuff should be overloaded (if used at all)
  2. In GSCF's Template.groovy domain class were the following methods that are not yet ported to GDT:

class Template {
... etc ...

/ The owner of the template. If the owner is not defined, it is a shared/public template */
SecUser owner


  • Creates a clone of the given other template. The currently logged in user
  • is set as the owner
  • @param otherTemplate *

public GscfTemplate?( GscfTemplate? otherTemplate, SecUser? owner ) {


authenticationService = new AuthenticationService?()

this.name = otherTemplate.name + " (Copy)"
this.description = otherTemplate.description
this.entity = otherTemplate.entity
this.owner = owner

The fields are copied by reference
this.fields = []
otherTemplate.fields.each {

this.fields.add( it )




  • Creates a clone of the given other template and also copies its owner *
  • @param otherTemplate *

public GscfTemplate?( GscfTemplate? otherTemplate) {

this( otherTemplate, otherTemplate.owner )



public static parse(Object xmlObject, SecUser? loggedInUser) {

def t = new GscfTemplate?();
t.name = xmlObject?.name?.text()
t.description = xmlObject?.description?.text()

Check whether a correct entity is given. The parseEntity method might
throw a ClassNotFoundException?, but that is OK, it should be thrown if the class
doesn't exist.
def entity = TemplateEntity?.parseEntity( xmlObject.entity?.text() );
if( !entity ) {

throw new Exception( "Incorrect entity given" );


t.entity = entity

Set the owner to the currently logged in user
t.owner = loggedInUser

Set all template fields
xmlObject.templateFields.templateField.each {

def field = TemplateField?.parse( it, entity );

Check whether a similar field already exists. For that, we search in all
template fields with the same name, in order to have as little comparisons
as possible
for( def otherField in TemplateField?.findAllByName( field?.name ) ) {

if( field.contentEquals( otherField ) ) {

field = otherField;



t.addToFields( field );


return t



comment:3 Changed 6 years ago by robert@…

I think something has to be done with the tests too. Integration tests now won't run because of exceptions:

[groovyc] Compiling 7 source files to /home/robert/.grails/1.3.6/projects/gscf/test-classes/integration
[groovyc] org.codehaus.groovy.control.MultipleCompilationErrorsException?: startup failed:
[groovyc] /home/robert/projects/grails/gscf/test/integration/gscf/OntologyTests.groovy: 81: unable to resolve class Term
[groovyc] @ line 81, column 14.
[groovyc] def term = new Term(
[groovyc] /home/robert/projects/grails/gscf/test/integration/gscf/SampleTests.groovy: 4: unable to resolve class dbnp.studycapturing.Template
[groovyc] @ line 4, column 1.
[groovyc] import dbnp.studycapturing.Template

[groovyc] /home/robert/projects/grails/gscf/test/integration/gscf/SampleTests.groovy: 8: unable to resolve class dbnp.studycapturing.TemplateFieldType?
[groovyc] @ line 8, column 1.
[groovyc] import dbnp.studycapturing.TemplateFieldType?
[groovyc] /home/robert/projects/grails/gscf/test/integration/gscf/SubjectTests.groovy: 52: unable to resolve class Term
[groovyc] @ line 52, column 19.
[groovyc] def humanTerm = new Term(

[groovyc] /home/robert/projects/grails/gscf/test/integration/gscf/SubjectTests.groovy: 187: unable to resolve class Ontology
[groovyc] @ line 187, column 12.
[groovyc] Ontology speciesOntology = speciesOntologies.asList().first()
[groovyc] 5 errors

comment:4 Changed 6 years ago by robert@…

I've fixed these compilation errors myself, but still the integration tests won't run. Using GROM it says something about classdefnotfound, but it gives no information.

comment:5 Changed 6 years ago by work@…

  • moved the templateEditor into the gdt plugin in r1439 and gdt revision 87, gdt to 0.0.3
  • fixed problem that the study wizard did not work (#286) in r1441, and gdt revision 91. gdt to 0.0.4
  • refactored the importer to use the dynamic entities provided by gdt 0.0.5 instead of using hardcoded entities in Config.groovy in r1443, gdt revision 92

comment:6 Changed 6 years ago by work@…

  • Component changed from General to Core Functionality
  • Type changed from defect to task

comment:7 Changed 6 years ago by work@…

removed Identity from the project in r1451 and changed the gdt imports in r1452

comment:8 Changed 6 years ago by work@…

  • Type changed from task to enhancement

comment:9 Changed 6 years ago by work@…

also pick up 'owner' in Template (see #226)

comment:10 Changed 6 years ago by work@…

  • added float support to Reltime input (#292, r1460)
  • moved (wizard) template tags to gdt in r1461
  • moved js, css and termEditor into gdt in r1467
  • gdt to 0.0.7 in r1468

todo: 'Module' is currently tightly integrated into gdt, this should be loosly coupled as Module is gscf specific and not a generic entity...

comment:11 Changed 6 years ago by work@…

Separated biological entities (Ontology / Term) from "gdt" into "bgdt" (biological grails domain templates) in gdt revision 105, bgdt revision 102 and gscf revision r1488

  • gdt
    • started working on extendability of the Template model by refactoring TemplateEntity? to use a generic validator
    • to 0.0.8
  • bgdt
    • added Ontology, Term, termEditor and related jar's
    • to 0.0.2

comment:12 Changed 6 years ago by work@…

Updated GDT & BGST in r1537

  • GDT up to 0.0.12 (dynamic injection of templateFields through ASTTransformations before compilation to byteCode)
  • BGDT up to 0.0.6 (depends on GDT 0.0.12)
  • TODO
    • have TemplateFieldType? dynamically extended by ASTTranformation, or rewrite the TemplateFieldType? system altogether
    • TemplateEntity? depends on any child plugin, as the child plugin may contain classes it requires in the hasMany relation (e.g. hasmany terms: Term). So we need to see if TemplateEntity? can have dynamic imports using ASTTransformation
    • seperate TemplateEditor? fields into the child plugin(s)

comment:13 Changed 6 years ago by work@…

  • Status changed from new to closed
  • Resolution set to fixed

closing this ticket as GDT is becoming pretty mature...

Note: See TracTickets for help on using tickets.