source: trunk/grails-app/controllers/dbnp/studycapturing/TemplateEditorController.groovy @ 1426

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