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

Last change on this file since 544 was 544, checked in by roberth, 12 years ago

Template editor is now able to add, edit, move and delete fields. Also fixed bug #90 (searching publications in IE didn't work because fetching XML from another domain was not allowed)

  • Property svn:keywords set to Date Author Rev
File size: 9.2 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: 544 $
12 * $Author: roberth $
13 * $Date: 2010-06-09 10:46:22 +0000 (wo, 09 jun 2010) $
14 */
15package dbnp.studycapturing
16import dbnp.data.*
17import dbnp.studycapturing.*
18import cr.co.arquetipos.crypto.Blowfish
19import grails.converters.*
20
21class TemplateEditorController {
22    def entityName;
23    def entity;
24
25    /**
26     * index closure
27     */
28    def index = {
29        // Check whether a right entity is given
30        _checkEntity();
31
32        // fetch all templates for this entity
33        def templates = Template.findAllByEntity(entity)
34
35        // Check whether a template is already selected
36        def selectedTemplate = params.template;
37        def template = null;
38
39        if( selectedTemplate ) {
40            template = Template.get( selectedTemplate );
41        }
42
43        return [
44            entity: entity,
45            templates: templates,
46            encryptedEntity: params.entity,
47            fieldTypes: TemplateFieldType.list(),
48           
49            template: template
50        ];
51    }
52
53    /**
54     * Shows an error page
55     *
56     * TODO: improve the error page
57     */
58    def error = {
59        render( 'view': 'error' );
60    }
61
62    /**
63     * Adds a new template field using a AJAX call
64         *
65         * @param template      ID of the template to add a field to
66         * @return                      JSON object with two entries:
67         *                                              id: [id of this object]
68         *                                              html: HTML to replace the contents of the LI-item that was updated.
69         *                                      On error the method gives a HTTP response status 500 and the error
70     */
71    def addField = {
72        // Search for the template
73        def template = Template.get( params.template );
74
75        if( !template ) {
76            response.status = 404;
77            render 'Template not found';
78            return;
79        }
80
81                // Create the template field and add it to the template
82                def templateField = new TemplateField( params );
83        if (templateField.save(flush: true)) {
84                        template.fields.add( templateField );
85
86                        def html = g.render( template: 'elements/liContent', model: [templateField: templateField, fieldTypes: TemplateFieldType.list()] );
87                        def output = [ id: templateField.id, html: html ];
88                        render output as JSON;
89
90            //render '';
91        } else {
92            response.status = 500;
93            render 'TemplateField could not be added because errors occurred.';
94            return
95        }
96    }
97
98    /**
99     * Updates a selected template field using a AJAX call
100         *
101         * @param id    ID of the field to update
102         * @return              JSON object with two entries:
103         *                                      id: [id of this object]
104         *                                      html: HTML to replace the contents of the LI-item that was updated.
105         *                              On error the method gives a HTTP response status 500 and the error
106     */
107    def update = {
108        // Search for the template field
109        def templateField = TemplateField.get( params.id );
110        if( !templateField ) {
111            response.status = 404;
112            render 'TemplateField not found';
113            return;
114        }
115
116        // Update the field if it is not updated in between
117        if (params.version) {
118            def version = params.version.toLong()
119            if (templateField.version > version) {
120                response.status = 500;
121                render 'TemplateField was updated while you were working on it. Please reload and try again.';
122                return
123            }
124        }
125        templateField.properties = params
126        if (!templateField.hasErrors() && templateField.save(flush: true)) {
127                        def html = g.render( template: 'elements/liContent', model: [templateField: templateField, fieldTypes: TemplateFieldType.list()] );
128                        def output = [ id: templateField.id, html: html ];
129                        render output as JSON;
130        } else {
131            response.status = 500;
132            render 'TemplateField was not updated because errors occurred.';
133            return
134        }
135    }
136
137    /**
138     * Deletes a selected template field from the template using a AJAX call
139         *
140         * @param templateField ID of the field to update
141         * @param template              ID of the template for which the field should be removed
142         * @return                              Status code 200 on success, 500 otherwise
143     */
144    def delete = {
145        // Search for the template
146        def template = Template.get( params.template );
147
148        if( !template ) {
149            response.status = 404;
150            render 'Template not found';
151            return;
152        }
153
154        // Search for the template field
155        def templateField = TemplateField.get( params.templateField );
156        if( !templateField ) {
157            response.status = 404;
158            render 'TemplateField not found';
159            return;
160        }
161
162        // The template field should exist within the template
163        if( !template.fields.contains( templateField ) ) {
164            response.status = 404;
165            render 'TemplateField not found within template';
166            return;
167        }
168
169                // Delete the field from this template
170        def currentIndex = template.fields.indexOf( templateField );
171        template.fields.remove( currentIndex );
172                template.save();
173                render '';
174
175                /*
176                 *try {
177                        templateField.delete(flush: true)
178                        render "";
179                        return;
180                } catch (org.springframework.dao.DataIntegrityViolationException e) {
181                        response.status = 500;
182                        render "Templatefield not deleted: " + e.getMessage();
183                        return;
184                }
185                */
186    }
187
188    /**
189     * Moves a template field using a AJAX call
190     *
191         * @param template              ID of the template that contains this field
192         * @param templateField ID of the templatefield to move
193         * @param position              New index of the templatefield in the array. The index is 0-based.
194         * @return                              JSON object with two entries:
195         *                                                      id: [id of this object]
196         *                                                      html: HTML to replace the contents of the LI-item that was updated.
197         *                                              On error the method gives a HTTP response status 500 and the error
198     */
199    def move = {
200        // Search for the template
201        def template = Template.get( params.template );
202
203        if( !template ) {
204            response.status = 404;
205            render 'Template not found';
206            return;
207        }
208
209        // Search for the template field
210        def  templateField = TemplateField.get( params.templateField );
211        if( !templateField ) {
212            response.status = 404;
213            render 'TemplateField not found';
214            return;
215        }
216
217        // The template field should exist within the template
218        if( !template.fields.contains( templateField ) ) {
219            response.status = 404;
220            render 'TemplateField not found within template';
221            return;
222        }
223
224        // Move the item
225        def currentIndex = template.fields.indexOf( templateField );
226        def moveField = template.fields.remove( currentIndex );
227        template.fields.add( Integer.parseInt( params.position ), moveField );
228
229                def html = g.render( template: 'elements/liContent', model: [templateField: templateField, fieldTypes: TemplateFieldType.list()] );
230                def output = [ id: templateField.id, html: html ];
231                render output as JSON;
232    }
233
234    /**
235     * Checks whether a correct entity is given
236         *
237         * @return      boolean True if a correct entity is given. Returns false and raises an error otherwise
238         * @see         error()
239     */
240    def _checkEntity = {
241        // got a entity get parameter?
242        entityName = _parseEntityType();
243
244        if( !entityName ) {
245            error();
246            return false;
247        }
248
249        // Create an object of this type
250        entity = _getEntity( entityName );
251
252        if( !entity ) {
253            error();
254            retur; false
255        }
256
257        return true;
258    }
259
260
261    /**
262     * Checks whether the entity type is given and can be parsed
263         *
264         * @return      Name of the entity if parsing is succesful, false otherwise
265     */
266    def _parseEntityType() {
267        def entityName;
268        if (params.entity) {
269            // decode entity get parameter
270            if (grailsApplication.config.crypto) {
271                    // generate a Blowfish encrypted and Base64 encoded string.
272                    entityName = Blowfish.decryptBase64(
273                            params.entity,
274                            grailsApplication.config.crypto.shared.secret
275                    )
276            } else {
277                    // base64 only; this is INSECURE! Even though it is not
278                    // very likely, it is possible to exploit this and have
279                    // Grails dynamically instantiate whatever class you like.
280                    // If that constructor does something harmfull this could
281                    // be dangerous. Hence, use encryption (above) instead...
282                    entityName = new String(params.entity.toString().decodeBase64())
283            }
284
285            return entityName;
286        } else {
287            return false;
288        }
289    }
290
291    /**
292     * Creates an object of the given entity.
293         *
294         * @return False if the entity is not a subclass of TemplateEntity
295     */
296    def _getEntity( entityName ) {
297        // Find the templates
298        def entity = Class.forName(entityName, true, this.getClass().getClassLoader())
299
300        // succes, is entity an instance of TemplateEntity?
301        if (entity.superclass =~ /TemplateEntity$/) {
302            return entity;
303        } else {
304            return false;
305        }
306
307    }
308}
Note: See TracBrowser for help on using the repository browser.