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

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

Fix asset copy failure due to to asset sub item non-unique names.

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