root/trunk/grails-app/controllers/dbnp/studycapturing/TemplateEditorController.groovy @ 1312

Revision 1312, 29.7 KB (checked in by work@…, 3 years ago)

- removed debug line

  • Property svn:keywords set to Author Date Rev
Line 
1/**
2 * TemplateEditorController Controler
3 *
4 * Webflow driven template editor
5 *
6 * @author  Jeroen Wesbeek
7 * @since       20100415
8 * @package     studycapturing
9 *
10 * Revision information:
11 * $Rev$
12 * $Author$
13 * $Date$
14 */
15package dbnp.studycapturing
16import dbnp.data.*
17import dbnp.studycapturing.*
18
19import dbnp.authentication.AuthenticationService
20import grails.plugins.springsecurity.Secured
21
22import cr.co.arquetipos.crypto.Blowfish
23import grails.converters.*
24import java.lang.reflect.*;
25
26@Secured(['IS_AUTHENTICATED_REMEMBERED'])
27class TemplateEditorController {
28    def entityName;
29    def entity;
30        def authenticationService
31
32        /**
33     * Fires after every action and determines the layout of the page
34     */
35    def afterInterceptor = { model, modelAndView ->
36      if ( params['standalone'] && params['standalone'] == 'true') {
37        model.layout = 'main';
38        model.extraparams = [ 'standalone': 'true' ] ;
39      } else {
40        model.layout = 'dialog';
41        model.extraparams = [] ;
42      }
43    }
44       
45        /**
46    * Study template editor page
47        */
48        def study = {
49            showEntity('dbnp.studycapturing.Study')
50    }
51
52        /**
53    * Subject template editor page
54        */
55        def subject = {
56            showEntity('dbnp.studycapturing.Subject')
57    }
58
59        /**
60    * Event template editor page
61        */
62        def event = {
63            showEntity('dbnp.studycapturing.Event')
64    }
65
66        /**
67    * Sampling Event template editor page
68        */
69        def samplingEvent = {
70            showEntity('dbnp.studycapturing.SamplingEvent')
71    }
72
73        /**
74    * Event template editor page
75        */
76        def sample = {
77            showEntity('dbnp.studycapturing.Sample')
78    }
79
80        /**
81    * Assay template editor page
82        */
83        def assay = {
84            showEntity('dbnp.studycapturing.Assay')
85    }
86
87        /**
88         * Show the template editor page for a particular entity
89         * @param targetEntity The full class name of the target entity
90         */
91        private void showEntity(String targetEntity) {
92                String resultEntity
93                if (grailsApplication.config.crypto) {
94                        // if a shared secret is defined, encrypt using that
95                        resultEntity = Blowfish.encryptBase64(
96                                        targetEntity.toString(),
97                                        grailsApplication.config.crypto.shared.secret
98                                )
99                }
100                else {
101                        // otherwise use standard encoding
102                        resultEntity = targetEntity.toString().bytes.encodeBase64()
103                }
104
105                // redirect to template editor page of the specified entity
106                params.entity = resultEntity
107                redirect(action: "index", params:params)
108        }
109
110    /**
111     * index closure
112     */
113    def index = {
114        // Check whether a right entity is given
115        if( !_checkEntity() ) {
116                        return
117                }
118
119        // fetch all templates for this entity
120        def templates = Template.findAllByEntity(entity)
121
122                // Generate a human readable entity name
123                def parts = entityName.tokenize( '.' );
124                def humanReadableEntity = parts[ parts.size() - 1 ];
125
126        return [
127            entity: entity,
128            templates: templates,
129            encryptedEntity: params.entity,
130            humanReadableEntity: humanReadableEntity,
131                        ontologies: params.ontologies
132        ];
133    }
134
135    /**
136     * compare two or more templates
137     */
138    def compare = {
139        // Check whether a right entity is given
140        if( !_checkEntity() ) {
141                        return
142                }
143
144        // fetch all templates for this entity
145        def templates = Template.findAllByEntity(entity)
146
147                // Find all available fields
148                def allFields = TemplateField.findAllByEntity( entity ).sort { a, b -> a.name <=> b.name }
149
150                // Generate a human readable entity name
151                def parts = entityName.tokenize( '.' );
152                def humanReadableEntity = parts[ parts.size() - 1 ];
153
154        return [
155            entity: entity,
156            templates: templates,
157                        allFields: allFields,
158            encryptedEntity: params.entity,
159            humanReadableEntity: humanReadableEntity,
160                        ontologies: params.ontologies,
161                        templateEntities: this.templateEntityList()
162        ];
163    }
164
165        /**
166         * Shows the editing of a template
167         */
168        def template = {
169        // Check whether a right entity is given
170        if( !_checkEntity() ) {
171                        return
172                }
173
174        // Check whether a template is selected. If not, redirect the user to the index
175        def selectedTemplate = params.template;
176        def template = null;
177                def domainFields = null;
178
179        if( selectedTemplate ) {
180            template = Template.get( selectedTemplate );
181                        domainFields = template.entity.giveDomainFields();
182        } else {
183                        redirect(action:"index",params:[entity:params.entity])
184                        return;
185                }
186
187        // fetch all templates for this entity
188        def templates = Template.findAllByEntity(entity)
189
190                // Generate a human readable entity name
191                def parts = entityName.tokenize( '.' );
192                def humanReadableEntity = parts[ parts.size() - 1 ];
193
194                // Find all available fields
195                def allFields = TemplateField.findAllByEntity( entity ).sort { a, b -> a.name <=> b.name }
196
197        return [
198            entity: entity,
199            templates: templates,
200            encryptedEntity: params.entity,
201            fieldTypes: TemplateFieldType.list(),
202                        ontologies: Ontology.list(),
203            humanReadableEntity: humanReadableEntity,
204
205            template: template,
206                        allFields: allFields,
207                        domainFields: domainFields
208        ];
209
210        }
211
212
213    /**
214     * Shows an error page
215     *
216     * TODO: improve the error page
217     */
218    def error = {
219        render( 'view': 'error' );
220    }
221
222    /**
223     * Creates a new template using a AJAX call
224         *
225         * @return                      JSON object with two entries:
226         *                                              id: [id of this object]
227         *                                              html: HTML to replace the contents of the LI-item that was updated.
228         *                                      On error the method gives a HTTP response status 500 and the error
229     */
230   def createTemplate = {
231                // Decode the entity
232        if( !_checkEntity() ) {
233                        response.status = 500;
234                        render "Incorrect entity given";
235                        return;
236                }
237
238                // set entity
239                params.entity = entity;
240
241                // Create the template fields and add it to the template
242                def template = new Template( params );
243        if (template.validate() && template.save(flush: true)) {
244                        def html = g.render( template: 'elements/liTemplate', model: [template: template] );
245                        def output = [ id: template.id, html: html ];
246                        render output as JSON;
247        } else {
248            response.status = 500;
249            render 'Template could not be created because errors occurred.';
250            return
251        }
252    }
253
254    /**
255     * Clones a template using a AJAX call
256         *
257         * @return                      JSON object with two entries:
258         *                                              id: [id of this object]
259         *                                              html: HTML of the contents of the LI-item that will be added.
260         *                                      On error the method gives a HTTP response status 500 and the error
261     */
262     def cloneTemplate = {
263        // Search for the template field
264        def template = Template.get( params.id );
265        if( !template ) {
266            response.status = 404;
267            render 'Template not found';
268            return;
269        }
270
271                // Create the template fields and add it to the template
272                def newTemplate = new Template( template, authenticationService.getLoggedInUser() );
273        if (newTemplate.validate() && newTemplate.save(flush: true)) {
274                        def html = g.render( template: 'elements/liTemplate', model: [template: newTemplate] );
275                        def output = [ id: newTemplate.id, html: html ];
276                        render output as JSON;
277        } else {
278            response.status = 500;
279            render 'Template could not be cloned because errors occurred.';
280            return
281        }
282    }
283
284    /**
285     * Updates a selected template using a AJAX call
286         *
287         * @param id    ID of the template to update
288         * @return              JSON object with two entries:
289         *                                      id: [id of this object]
290         *                                      html: HTML to replace the contents of the LI-item that was updated.
291         *                              On error the method gives a HTTP response status 500 and the error
292     */
293    def updateTemplate = {
294        // Search for the template field
295        def template = Template.get( params.id );
296        if( !template ) {
297            response.status = 404;
298            render 'Template not found';
299            return;
300        }
301
302        // Update the field if it is not updated in between
303        if (params.version) {
304            def version = params.version.toLong()
305            if (template.version > version) {
306                response.status = 500;
307                render 'Template was updated while you were working on it. Please reload and try again.';
308                return
309            }
310        }
311
312        template.properties = params
313        if (!template.hasErrors() && template.save(flush: true)) {
314                        def html = g.render( template: 'elements/liTemplate', model: [template: template] );
315                        def output = [ id: template.id, html: html ];
316                        render output as JSON;
317        } else {
318            response.status = 500;
319            render 'Template was not updated because errors occurred.';
320            return
321        }
322    }
323
324    /**
325     * Deletes a template using a AJAX call
326     *
327         * @param template              ID of the template to move
328         * @return                              JSON object with one entry:
329         *                                                      id: [id of this object]
330         *                                              On error the method gives a HTTP response status 500 and the error
331     */
332    def deleteTemplate = {
333        // Search for the template field
334        def  template = Template.get( params.template );
335        if( !template ) {
336            response.status = 404;
337            render 'Template not found';
338            return;
339        }
340
341        // Delete the template field
342                try {
343                        template.delete(flush: true)
344
345                        def output = [ id: template.id ];
346                        render output as JSON;
347                }
348                catch (org.springframework.dao.DataIntegrityViolationException e) {
349            response.status = 500;
350            render 'Template could not be deleted: ' + e.getMessage();
351                }
352    }
353
354    /**
355     * Creates a new template field using a AJAX call
356         *
357         * @param template      ID of the template to add a field to
358         * @return                      JSON object with two entries:
359         *                                              id: [id of this object]
360         *                                              html: HTML to replace the contents of the LI-item that was updated.
361         *                                      On error the method gives a HTTP response status 500 and the error
362     */
363    def createField = {
364        // Search for the template
365        def template = Template.get( params.template );
366
367        if( !template ) {
368            response.status = 404;
369            render 'Template not found';
370            return;
371        }
372
373                // Decode the entity, in order to set a good property
374        if( !_checkEntity() ) {
375                        response.status = 500;
376                        render "Incorrect entity given";
377                        return;
378                }
379
380                params.entity = entity;
381
382                // See whether this field already exists. It is checked by name, type and unit and entity
383                // The search is done using search by example (see http://grails.org/DomainClass+Dynamic+Methods, method find)
384                def uniqueParams = [ name: params.name, type: params.type, unit: params.unit, entity: params.entity ];
385                if( TemplateField.find( new TemplateField( uniqueParams ) ) ) {
386                        response.status = 500;
387                        render "A field with this name, type and unit already exists.";
388                        return;
389                }
390
391                // See whether this exists as domain field. If it does, raise an error
392                def domainFields = template.entity.giveDomainFields()
393                if( domainFields.find { it.name.toLowerCase() == params.name.toLowerCase() } ) {
394                        response.status = 500;
395                        render "All templates for entity " + template.entity + " contain a domain field with name " + params.name + ". You can not create a field with this name.";;
396                        return;
397                }
398
399                // If this field is type stringlist, we have to prepare the parameters
400                if( params.type.toString() == 'STRINGLIST' ) {
401                        def listEntries = [];
402                        params.listEntries.eachLine {
403                                // We don't search for a listitem that might already exist,
404                                // because if we use that list item, it will be removed from the
405                                // other string list.
406                                def name = it.trim();
407
408                                def listitem = new TemplateFieldListItem( name: name )
409                                listEntries.add( listitem );
410                        }
411
412                        params.listEntries = listEntries;
413                } else {
414                        params.remove( 'listEntries' );
415                }
416
417                // If this field isnot a ontologyterm, we should remove the ontologies
418                if( params.type.toString() != 'ONTOLOGYTERM' ) {
419                        params.remove( 'ontologies' );
420                }
421
422                // Create the template field and add it to the template
423                def templateField = new TemplateField( params );
424        if (templateField.save(flush: true)) {
425
426                        def html = g.render( template: 'elements/available', model: [templateField: templateField, ontologies: Ontology.list(), fieldTypes: TemplateFieldType.list()] );
427                        def output = [ id: templateField.id, html: html ];
428                        render output as JSON;
429
430            //render '';
431        } else {
432            response.status = 500;
433            render 'TemplateField could not be created because errors occurred.';
434            return
435        }
436    }
437
438    /**
439     * Updates a selected template field using a AJAX call
440         *
441         * @param id    ID of the field to update
442         * @return              JSON object with two entries:
443         *                                      id: [id of this object]
444         *                                      html: HTML to replace the contents of the LI-item that was updated.
445         *                              On error the method gives a HTTP response status 500 and the error
446     */
447    def updateField = {
448        // Search for the template field
449        def templateField = TemplateField.get( params.id );
450        if( !templateField ) {
451            response.status = 404;
452            render 'TemplateField not found';
453            return;
454        }
455
456        // Update the field if it is not updated in between
457        if (params.version) {
458            def version = params.version.toLong()
459            if (templateField.version > version) {
460                response.status = 500;
461                render 'TemplateField was updated while you were working on it. Please reload and try again.';
462                return
463            }
464        }
465
466                // If this field is type stringlist or ontology, we have to prepare the parameters
467                //
468                // For stringlist and ontologyterm fields, the list items can be changed, even when the field is in use
469                // In that case, only never-used items can be removed or changed and items can be added. If that is the case
470                // params.is_disabled is true and we should combine listEntries and extraListEntries with the items already in use.
471                if( params.type.toString() == 'STRINGLIST' || ( templateField.type == TemplateFieldType.STRINGLIST && params.is_disabled) ) {
472                        def listEntryLines = "";
473                        def listEntries = [];
474
475                        if( params.is_disabled ) {
476                                listEntries = templateField.getUsedListEntries();
477                        }
478
479                        if( params.listEntries ) {
480                                listEntryLines = params.listEntries;
481                               
482                                listEntryLines.eachLine {
483                                        // We don't search for a listitem that might already exist,
484                                        // because if we use that list item, it will be removed from the
485                                        // other string list. We only search for an item that already
486                                        // belongs to this list.
487                                        def name = it.trim();
488
489                                        def c = TemplateFieldListItem.createCriteria()
490                                        def listitem = c.get {
491                                                eq( "name", name )
492                                                eq( "parent", templateField)
493                                        }
494                                        if( !listitem ) {
495                                                listitem = new TemplateFieldListItem( name: name )
496                                        }
497
498                                        // Prevent using the same list entry twice
499                                        if( !listEntries.contains( listitem ) )
500                                                listEntries.add( listitem );
501                                }
502                        }
503
504                        // Add listEntries to the templateField
505                        params.listEntries = listEntries;
506                } else {
507                        params.remove( 'listEntries' );
508                }
509
510                // If this field is a ontologyterm, we add ontology objects
511                // For stringlist and ontologyterm fields, the list items can be changed, even when the field is in use
512                // In that case, only never-used items can be removed or changed and items can be added. If that is the case
513                // params.is_disabled is true and we should combine ontologies with the ontologies already in use.
514                if( ( params.type.toString() == 'ONTOLOGYTERM' || ( templateField.type == TemplateFieldType.ONTOLOGYTERM && params.is_disabled ) ) && params.ontologies ) {
515                        def usedOntologies = [];
516
517                        if( params.is_disabled ) {
518                                usedOntologies = templateField.getUsedOntologies();
519                        }
520
521                        if( params.ontologies ) {
522                                def ontologies = params.ontologies;
523       
524                                params.ontologies = usedOntologies + Ontology.getAll( ontologies.collect { Integer.parseInt( it ) } );
525                        }
526
527                } else {
528                        params.remove( 'ontologies' );
529                }
530
531                // A field that is already used in one or more templates, but is not filled everywhere,
532                // can not be set to required
533                if( params.required ) {
534                        if( !templateField.isFilledInAllObjects() ) {
535                                response.status = 500;
536                                render "A field can only be marked as required if all objects using this field have a value for the field."
537                                return
538                        }
539                }
540
541                // Set all parameters
542                templateField.properties = params
543
544                templateField.validate();
545               
546
547        if (!templateField.hasErrors() && templateField.save(flush: true)) {
548
549                        // Remove all orphaned list items, because grails doesn't handle it for us
550                        TemplateFieldListItem.findAllByParent( templateField ).each {
551                                if( !params.listEntries.contains( it ) ) {
552                                        templateField.removeFromListEntries( it );
553                                        it.delete();
554                                }
555                        }
556
557                        // Select the template to use for the HTML output
558                        def renderTemplate = 'elements/available';
559                        if( params.renderTemplate == 'selected' ) {
560                                renderTemplate = 'elements/selected';
561                        }
562
563                        // Selected fields should have a template given
564                        def template = null;
565                        if( params.templateId )
566                                template = Template.findById( params.templateId );
567                       
568                        def html = g.render( template: renderTemplate, model: [template: template, templateField: templateField, ontologies: Ontology.list(), fieldTypes: TemplateFieldType.list()] );
569                        def output = [ id: templateField.id, html: html ];
570                        render output as JSON;
571        } else {
572            response.status = 500;
573            render 'TemplateField was not updated because errors occurred. Please contact the system administrator';
574            return
575        }
576    }
577
578    /**
579     * Deletes a template field using a AJAX call
580     *
581         * @param templateField ID of the templatefield to move
582         * @return                              JSON object with one entry:
583         *                                                      id: [id of this object]
584         *                                              On error the method gives a HTTP response status 500 and the error
585     */
586    def deleteField = {
587        // Search for the template field
588        def  templateField = TemplateField.get( params.templateField );
589        if( !templateField ) {
590            response.status = 404;
591            render 'TemplateField not found';
592            return;
593        }
594
595        // Delete the template field
596                try {
597                        templateField.delete(flush: true)
598
599                        def output = [ id: templateField.id ];
600                        render output as JSON;
601                }
602                catch (org.springframework.dao.DataIntegrityViolationException e) {
603            response.status = 500;
604            render 'TemplateField could not be deleted: ' + e.getMessage();
605                }
606    }
607
608    /**
609     * Adds a new template field to a template using a AJAX call
610         *
611         * @param template      ID of the template to add a field to
612         * @return                      JSON object with two entries:
613         *                                              id: [id of this object]
614         *                                              html: HTML to replace the contents of the LI-item that was updated.
615         *                                      On error the method gives a HTTP response status 404 or 500 and the error
616     */
617    def addField = {
618        // Search for the template
619        def template = Template.get( params.template );
620
621        if( !template ) {
622            response.status = 404;
623            render 'Template not found';
624            return;
625        }
626
627        // Search for the template field
628        def templateField = TemplateField.get( params.templateField );
629        if( !templateField ) {
630            response.status = 404;
631            render 'TemplateField does not exist';
632            return;
633        }
634
635        // The template field should exist within the template
636        if( template.fields.contains( templateField ) ) {
637            response.status = 500;
638            render 'TemplateField is already found within template';
639            return;
640        }
641
642                // If the template is in use, only non-required fields can be added
643                if( template.inUse() && templateField.required ) {
644                        response.status = 500;
645                        render 'Only non-required fields can be added to templates that are in use.'
646                        return;
647                }
648
649                // All field names within a template should be unique
650                if( template.fields.find { it.name.toLowerCase() == templateField.name.toLowerCase() } ) {
651                        response.status = 500;
652                        render 'This template already contains a field with name ' + templateField.name + '. Field names should be unique within a template.'
653                        return;
654                }
655
656                if( !params.position || Integer.parseInt( params.position ) == -1) {
657                        template.fields.add( templateField )
658                } else {
659                        template.fields.add( Integer.parseInt( params.position ), templateField )
660                }
661
662            if (!template.validate()) {
663                    response.status = 500;
664                    template.errors.each { render it}
665            }
666            template.save(flush:true);
667
668                def html = g.render( template: 'elements/selected', model: [templateField: templateField, template: template, ontologies: Ontology.list(), fieldTypes: TemplateFieldType.list()] );
669                def output = [ id: templateField.id, html: html ];
670                render output as JSON;
671    }
672
673    /**
674     * Removes a selected template field from the template using a AJAX call
675         *
676         * @param templateField ID of the field to update
677         * @param template              ID of the template for which the field should be removed
678         * @return                              JSON object with two entries:
679         *                                                      id: [id of this object]
680         *                                                      html: HTML to replace the contents of the LI-item that was updated.
681         *                                              On error the method gives a HTTP response status 404 or 500 and the error
682     */
683    def removeField = {
684        // Search for the template
685        def template = Template.get( params.template );
686
687        if( !template ) {
688            response.status = 404;
689            render 'Template not found';
690            return;
691        }
692
693        // Search for the template field
694        def templateField = TemplateField.get( params.templateField );
695        if( !templateField ) {
696            response.status = 404;
697            render 'TemplateField not found';
698            return;
699        }
700
701        // The template field should exist within the template
702        if( !template.fields.contains( templateField ) ) {
703            response.status = 404;
704            render 'TemplateField not found within template';
705            return;
706        }
707
708                // If the template is in use, field can not be removed
709                if( templateField.isFilledInTemplate(template) ) {
710                        response.status = 500;
711                        render 'Fields can not be removed from a template if it has been filled somewhere.'
712                        return;
713                }
714
715                // Delete the field from this template
716        def currentIndex = template.fields.indexOf( templateField );
717        template.fields.remove( currentIndex );
718                template.save(flush:true);
719
720
721                def html = g.render( template: 'elements/available', model: [templateField: templateField, ontologies: Ontology.list(), fieldTypes: TemplateFieldType.list()] );
722                def output = [ id: templateField.id, html: html ];
723                render output as JSON;
724    }
725
726    /**
727     * Moves a template field using a AJAX call
728     *
729         * @param template              ID of the template that contains this field
730         * @param templateField ID of the templatefield to move
731         * @param position              New index of the templatefield in the array. The index is 0-based.
732         * @return                              JSON object with two entries:
733         *                                                      id: [id of this object]
734         *                                                      html: HTML to replace the contents of the LI-item that was updated.
735         *                                              On error the method gives a HTTP response status 500 and the error
736     */
737    def moveField = {
738        // Search for the template
739        def template = Template.get( params.template );
740
741        if( !template ) {
742            response.status = 404;
743            render 'Template not found';
744            return;
745        }
746
747        // Search for the template field
748        def  templateField = TemplateField.get( params.templateField );
749        if( !templateField ) {
750            response.status = 404;
751            render 'TemplateField not found';
752            return;
753        }
754
755        // The template field should exist within the template
756        if( !template.fields.contains( templateField ) ) {
757            response.status = 404;
758            render 'TemplateField not found within template';
759            return;
760        }
761
762        // Move the item
763        def currentIndex = template.fields.indexOf( templateField );
764        def moveField = template.fields.remove( currentIndex );
765
766        template.fields.add( Integer.parseInt( params.position ), moveField );
767                template.save(flush:true);
768
769                def html = g.render( template: 'elements/selected', model: [templateField: templateField, template: template, fieldTypes: TemplateFieldType.list()] );
770                def output = [ id: templateField.id, html: html ];
771                render output as JSON;
772    }
773
774        /**
775         * Checks how many template use a specific template field
776         *
777         * @param       id      ID of the template field
778         * @return      int     Number of uses
779         */
780        def numFieldUses = {
781        // Search for the template field
782        def  templateField = TemplateField.get( params.id );
783        if( !templateField ) {
784            response.status = 404;
785            render 'TemplateField not found';
786            return;
787        }
788
789                render templateField.numUses();
790        }
791
792        /**
793         * Adds a ontolgy based on the ID given
794         *
795         * @param       ncboID
796         * @return      JSON    Ontology object
797         */
798        def addOntologyById = {
799                def id = params.ncboID;
800
801                if( !id ) {
802                        response.status = 500;
803                        render 'No ID given'
804                        return;
805                }
806
807                if( Ontology.findByNcboId( Integer.parseInt(  id ) ) ) {
808                        response.status = 500;
809                        render 'This ontology was already added to the system';
810                        return;
811                }
812
813                def ontology = null;
814
815                try {
816                        ontology = dbnp.data.Ontology.getBioPortalOntology( id );
817                } catch( Exception e ) {
818                        response.status = 500;
819                        render 'Ontology with ID ' + id + ' not found';
820                        return;
821                }
822
823                if( !ontology ) {
824                        response.status = 404;
825                        render 'Ontology with ID ' + id + ' not found';
826                        return;
827                }
828
829                // Validate ontology
830                if (!ontology.validate()) {
831                        response.status = 500;
832                        render ontology.errors.join( '; ' );
833                        return;
834                }
835
836                // Save ontology and render the object as JSON
837                ontology.save(flush: true)
838                render ontology as JSON
839        }
840
841        /**
842         * Adds a ontolgy based on the term ID given
843         *
844         * @param       ncboID
845         * @return      JSON    Ontology object
846         * @deprecated  User addOntologyById instead, using the ncboId given by the JSON call
847         */
848        def addOntologyByTerm = {
849                def id = params.termID;
850
851                if( !id ) {
852                        response.status = 500;
853                        render 'No ID given'
854                        return;
855                }
856
857                def ontology = null;
858
859                try {
860                        ontology = dbnp.data.Ontology.getBioPortalOntologyByTerm( id );
861                } catch( Exception e ) {
862                        response.status = 500;
863
864                        if( e.getMessage() )
865                                render e.getMessage()
866                        else
867                                render "Unknown error: " + e.getClass()
868                        return;
869                }
870
871                if( !ontology ) {
872                        response.status = 404;
873                        render 'Ontology form term ' + id + ' not found';
874                        return;
875                }
876
877                // Validate ontology
878                if (!ontology.validate()) {
879                        response.status = 500;
880                        render ontology.errors.join( '; ' );
881                        return;
882                }
883
884                // Save ontology and render the object as JSON
885                ontology.save(flush: true)
886                render ontology as JSON
887        }
888
889    /**
890     * Checks whether a correct entity is given
891         *
892         * @return      boolean True if a correct entity is given. Returns false and raises an error otherwise
893     */
894    def _checkEntity = {
895        // got a entity get parameter?
896        entityName = _parseEntityType();
897
898        if( !entityName ) {
899            error();
900            return false;
901        }
902
903        // Create an object of this type
904        entity = _getEntity( entityName );
905
906        if( !entity ) {
907            error();
908            return false
909        }
910
911        return true;
912    }
913
914
915    /**
916     * Checks whether the entity type is given and can be parsed
917         *
918         * @return      Name of the entity if parsing is succesful, false otherwise
919     */
920    def _parseEntityType() {
921        def entityName;
922        if (params.entity) {
923            // decode entity get parameter
924            if (grailsApplication.config.crypto) {
925                    // generate a Blowfish encrypted and Base64 encoded string.
926                    entityName = Blowfish.decryptBase64(
927                        params.entity,
928                        grailsApplication.config.crypto.shared.secret
929                                        )
930            } else {
931                    // base64 only; this is INSECURE! Even though it is not
932                    // very likely, it is possible to exploit this and have
933                    // Grails dynamically instantiate whatever class you like.
934                    // If that constructor does something harmfull this could
935                    // be dangerous. Hence, use encryption (above) instead...
936                    entityName = new String(params.entity.toString().decodeBase64())
937            }
938
939            return entityName;
940        } else {
941            return false;
942        }
943    }
944
945    /**
946     * Creates an object of the given entity.
947         *
948         * @return False if the entity is not a subclass of TemplateEntity
949     */
950    def _getEntity( entityName ) {
951        // Find the templates
952        def entity = Class.forName(entityName, true, this.getClass().getClassLoader())
953
954        // succes, is entity an instance of TemplateEntity?
955        if (entity.superclass =~ /TemplateEntity$/ || entity.superclass.superclass =~ /TemplateEntity$/) {
956            return entity;
957        } else {
958            return false;
959        }
960
961    }
962
963        def templateEntityList = {
964                def entities = [
965                        [ name: 'Study', entity: 'dbnp.studycapturing.Study' ],
966                        [ name: 'Subject', entity: 'dbnp.studycapturing.Subject' ],
967                        [ name: 'Event', entity: 'dbnp.studycapturing.Event' ],
968                        [ name: 'Sampling Event', entity: 'dbnp.studycapturing.SamplingEvent' ],
969                        [ name: 'Sample', entity: 'dbnp.studycapturing.Sample' ],
970                        [ name: 'Assay', entity: 'dbnp.studycapturing.Assay' ]
971                ]
972
973                entities.each {
974                        // add the entity class name to the element
975                        // do we have crypto information available?
976                        if (grailsApplication.config.crypto) {
977                                // generate a Blowfish encrypted and Base64 encoded string.
978                                it.encoded = URLEncoder.encode(
979                                        Blowfish.encryptBase64(
980                                                it.entity.toString().replaceAll(/^class /, ''),
981                                                grailsApplication.config.crypto.shared.secret
982                                        )
983                                )
984                        } else {
985                                // base64 only; this is INSECURE! As this class
986                                // is instantiated elsewehere. Possibly exploitable!
987                                it.encoded = URLEncoder.encode(it.entity.toString().replaceAll(/^class /, '').bytes.encodeBase64())
988                        }
989                }
990
991                return entities
992        }
993}
Note: See TracBrowser for help on using the browser.