source: trunk/grails-app/services/AssetService.groovy @ 352

Last change on this file since 352 was 352, checked in by gav, 10 years ago

Added some checks to prevent recurrsion loops in Asset tree.

File size: 7.8 KB
Line 
1class AssetService {
2
3    boolean transactional = false
4
5    def assetSubItemService
6
7    /**
8    * Determines and returns a possible list of asset sub items.
9    * @returns A list of the possible assetSubItems.
10    */
11    def possibleAssetSubItems() {
12        def criteria = AssetSubItem.createCriteria()
13        def possibleAssetSubItems = criteria.list() {
14            and {
15                eq('isActive', true)
16                isNull("parentItem")
17                }
18        }
19    }
20
21    def delete(params) {
22        Asset.withTransaction { status ->
23            def result = [:]
24
25            def fail = { Map m ->
26                status.setRollbackOnly()
27                if(result.assetInstance && m.field)
28                    result.assetInstance.errors.rejectValue(m.field, m.code)
29                result.error = [ code: m.code, args: ["Asset", params.id] ]
30                return result
31            }
32
33            result.assetInstance = Asset.get(params.id)
34
35            if(!result.assetInstance)
36                return fail(code:"default.not.found")
37
38            if(result.assetInstance.maintenanceActions)
39                return fail(code:"maintenanceActions.still.associated")
40
41            // Remove orphan assetSubItems.
42            def assetSubItems = new ArrayList(result.assetInstance.assetSubItems) // avoid ConcurrentModificationException.
43            def r
44            for(assetSubItem in assetSubItems) {
45                result.assetInstance.removeFromAssetSubItems(assetSubItem)
46                if(!assetSubItem.assets && !assetSubItem.parentItem) {
47                    r = assetSubItemService.delete(id: assetSubItem.id)
48                    if(r.error) {
49                        fail(code:"asset.subItems.delete.failure")
50                        break
51                    }
52                }
53            }
54
55            if(result.error)
56                return result
57
58            try {
59                result.assetInstance.delete(flush:true)
60                return result //Success.
61            }
62            catch(org.springframework.dao.DataIntegrityViolationException e) {
63                return fail(code:"default.delete.failure")
64            }
65
66        } // end withTransaction
67    } // end delete()
68
69    def create(params) {
70        def result = [:]
71        def fail = { Map m ->
72            result.error = [ code: m.code, args: ["Asset", params.id] ]
73            return result
74        }
75
76        result.assetInstance = new Asset()
77        result.assetInstance.properties = params
78
79        // success
80        return result
81    }
82
83    def copy(params) {
84        def result = [:]
85        def fail = { Map m ->
86            result.error = [ code: m.code, args: ["Asset", params.id] ]
87            return result
88        }
89
90        result.assetToCopy = Asset.get(params.assetToCopy?.id)
91
92        if(!result.assetToCopy)
93            return fail(code: "asset.copy.asset.required")
94
95        result.assetInstance = new Asset(name: result.assetToCopy.name,
96                                                            description: result.assetToCopy.description,
97                                                            comment: result.assetToCopy.comment,
98                                                            section: result.assetToCopy.section)
99
100        result.assetInstance.properties = params
101
102        // success
103        return result
104    }
105
106    def save(params) {
107        def result = [:]
108        def fail = { Map m ->
109            if(result.assetInstance && m.field) 
110                result.assetInstance.errors.rejectValue(m.field, m.code)
111            result.error = [ code: m.code, args: ["Asset", params.id] ]
112            return result
113        }
114
115        result.assetInstance = new Asset(params)
116
117        if(result.assetInstance.hasErrors() || !result.assetInstance.save(flush: true))
118            return fail(code:"default.create.failure")
119
120        // success
121        return result
122    }
123
124    def saveCopy(params) {
125        Asset.withTransaction { status ->
126            def result = [:]
127
128            def fail = { Map m ->
129                status.setRollbackOnly()
130                if(result.assetInstance && m.field)
131                    result.assetInstance.errors.rejectValue(m.field, m.code)
132                result.error = [ code: m.code, args: ["Asset", params.id] ]
133                return result
134            }
135
136            result.assetToCopy = Asset.get(params.assetToCopy?.id)
137            if(!result.assetToCopy)
138                return fail(code:"default.not.found")
139
140            if(!params.copyMethod)
141                fail(code:"asset.copy.method.required")
142
143            result.assetInstance =  new Asset(params)
144
145            if(result.assetInstance.hasErrors() || !result.assetInstance.save())
146                return fail(code:"default.create.failure")
147
148            def assetSubItemInstance1
149
150            // Copy subItems from level 2 and bellow.
151            def copyAssetSubItem = { assetSubItemToCopy, parentItem ->
152                def assetSubItemInstance = new AssetSubItem(name: assetSubItemToCopy.name,
153                                                                                            description: assetSubItemToCopy.description,
154                                                                                            parentItem: parentItem)
155
156                if(assetSubItemInstance.hasErrors() || !assetSubItemInstance.save())
157                    return fail(field:"subItems", code:"default.create.failure")
158
159                def i = 0
160                for(assetSubItem in assetSubItemToCopy.subItems) {
161                    call(assetSubItem, assetSubItemInstance)
162                    // Protect against endless recurrsion.
163                    i++
164                    if(i > 100)
165                        fail(code:"default.create.failure")
166                    // Stop if an error is flagged.
167                    if(result.error)
168                        break
169                }
170            } //copyAssetSubItem
171
172            // Copy the 1st level of subItems.
173            def copyAssetSubItem1 = { assetSubItemToCopy ->
174                assetSubItemInstance1 = new AssetSubItem(name: assetSubItemToCopy.name,
175                                                                                        description: assetSubItemToCopy.description,
176                                                                                        asset: result.assetInstance)
177
178                if(assetSubItemInstance1.hasErrors() || !assetSubItemInstance1.save())
179                    return fail(field:"assetSubItems", code:"default.create.failure")
180
181                result.assetInstance.addToAssetSubItems(assetSubItemInstance1)
182
183                def i = 0
184                for(assetSubItem in assetSubItemToCopy.subItems) {
185                    copyAssetSubItem(assetSubItem, assetSubItemInstance1)
186                    // Protect against endless recurrsion.
187                    i++
188                    if(i > 100)
189                        fail(code:"default.create.failure")
190                    // Stop if an error is flagged.
191                    if(result.error)
192                        break
193                }
194            } //copyAssetSubItem1
195
196            def linkAssetSubItem = { assetSubItemToLink ->
197                result.assetInstance.addToAssetSubItems(assetSubItemToLink)
198            }
199
200            def i = 0
201            for(assetSubItem in result.assetToCopy.assetSubItems) {
202
203                if(params.copyMethod == "copy")
204                    copyAssetSubItem1(assetSubItem)
205                else
206                    linkAssetSubItem(assetSubItem)
207                // Protect against endless recurrsion.
208                i++
209                if(i > 100)
210                    fail(code:"default.create.failure")
211                // Stop if an error is flagged.
212                if(result.error)
213                    break
214            }
215
216            // Success or not.
217            return result
218
219        } // end withTransaction
220    } // end saveCopySrvce
221
222} // end class
Note: See TracBrowser for help on using the repository browser.