ref #6730: fix delete media if it is used in taxonnamedescription
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / MediaServiceImpl.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.cdm.api.service;
11
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.Set;
15 import java.util.UUID;
16
17 import org.springframework.beans.factory.annotation.Autowired;
18 import org.springframework.stereotype.Service;
19 import org.springframework.transaction.annotation.Transactional;
20
21 import eu.etaxonomy.cdm.api.service.config.DeleteConfiguratorBase;
22 import eu.etaxonomy.cdm.api.service.config.MediaDeletionConfigurator;
23 import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableException;
24 import eu.etaxonomy.cdm.api.service.pager.Pager;
25 import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
26 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
27 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
28 import eu.etaxonomy.cdm.model.common.CdmBase;
29 import eu.etaxonomy.cdm.model.description.DescriptionBase;
30 import eu.etaxonomy.cdm.model.description.MediaKey;
31 import eu.etaxonomy.cdm.model.description.SpecimenDescription;
32 import eu.etaxonomy.cdm.model.description.TaxonDescription;
33 import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
34 import eu.etaxonomy.cdm.model.description.TextData;
35 import eu.etaxonomy.cdm.model.location.NamedArea;
36 import eu.etaxonomy.cdm.model.media.Media;
37 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
38 import eu.etaxonomy.cdm.model.media.Rights;
39 import eu.etaxonomy.cdm.model.name.TaxonName;
40 import eu.etaxonomy.cdm.model.occurrence.MediaSpecimen;
41 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
42 import eu.etaxonomy.cdm.model.taxon.Taxon;
43 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
44 import eu.etaxonomy.cdm.persistence.dao.media.IMediaDao;
45 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
46
47 @Service
48 @Transactional(readOnly=true)
49 public class MediaServiceImpl extends IdentifiableServiceBase<Media,IMediaDao> implements IMediaService {
50
51 @Override
52 @Autowired
53 protected void setDao(IMediaDao dao) {
54 this.dao = dao;
55 }
56
57 @Autowired
58 private IDescriptionService descriptionService;
59
60 @Autowired
61 private IOccurrenceService specimenService;
62 @Autowired
63 private ITaxonService taxonService;
64 @Autowired
65 private INameService nameService;
66
67 @Override
68 public Pager<MediaKey> getMediaKeys(Set<Taxon> taxonomicScope, Set<NamedArea> geoScopes, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
69 Integer numberOfResults = dao.countMediaKeys(taxonomicScope, geoScopes);
70
71 List<MediaKey> results = new ArrayList<MediaKey>();
72 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
73 results = dao.getMediaKeys(taxonomicScope, geoScopes, pageSize, pageNumber, propertyPaths);
74 }
75
76 return new DefaultPagerImpl<MediaKey>(pageNumber, numberOfResults, pageSize, results);
77 }
78
79 @Override
80 public Pager<Rights> getRights(Media t, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
81 Integer numberOfResults = dao.countRights(t);
82
83 List<Rights> results = new ArrayList<Rights>();
84 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
85 results = dao.getRights(t, pageSize, pageNumber,propertyPaths);
86 }
87
88 return new DefaultPagerImpl<Rights>(pageNumber, numberOfResults, pageSize, results);
89 }
90
91 /* (non-Javadoc)
92 * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)
93 */
94 @Override
95 @Transactional(readOnly = false)
96 public void updateTitleCache(Class<? extends Media> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<Media> cacheStrategy, IProgressMonitor monitor) {
97 //IIdentifiableEntityCacheStrategy<Media> cacheStrategy = MediaDefaultCacheStrategy();
98 if (clazz == null){
99 clazz = Media.class;
100 }
101 super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
102 }
103
104 /* (non-Javadoc)
105 * @see eu.etaxonomy.cdm.api.service.IMediaService#delete(java.util.UUID, eu.etaxonomy.cdm.api.service.config.MediaDeletionConfigurator)
106 */
107 @Override
108 @Transactional(readOnly=false)
109 public DeleteResult delete(UUID mediaUuid, MediaDeletionConfigurator config) {
110 DeleteResult result = new DeleteResult();
111 Media media = this.load(mediaUuid);
112
113 result = isDeletable(mediaUuid, config);
114 CdmBase updatedObject = null;
115 if (result.isOk()){
116 Set<CdmBase> references = commonService.getReferencingObjectsForDeletion(media);
117 String message = null;
118 for (CdmBase ref: references){
119
120 if (ref instanceof TextData){
121
122 TextData textData = HibernateProxyHelper.deproxy(ref, TextData.class);
123 DescriptionBase description = HibernateProxyHelper.deproxy(textData.getInDescription(), DescriptionBase.class);
124
125 if (description.isImageGallery()){
126 if (description instanceof TaxonDescription){
127 TaxonDescription desc = HibernateProxyHelper.deproxy(description, TaxonDescription.class);
128 if (desc.getTaxon() == null ){
129 continue;
130 } else if ( (config.isDeleteFromDescription() && config.getDeleteFrom() instanceof Taxon && config.getDeleteFrom().getId() == desc.getTaxon().getId())|| config.isDeleteFromEveryWhere()){
131 Taxon taxon = desc.getTaxon();
132 updatedObject = taxon;
133
134 while(textData.getMedia().contains(media)){
135 textData.removeMedia(media);
136 }
137 if (textData.getMedia().isEmpty()){
138 desc.removeElement(textData);
139 }
140 if (desc.getElements().isEmpty()){
141 taxon.removeDescription(desc);
142 }
143
144 } else {
145 // this should not be happen, because it is not deletable. see isDeletable
146 result.setAbort();
147
148
149 }
150 } else if (description instanceof SpecimenDescription){
151 SpecimenDescription desc = HibernateProxyHelper.deproxy(description, SpecimenDescription.class);
152 if (desc.getDescribedSpecimenOrObservation() == null ){
153 continue;
154 } else if ((config.isDeleteFromDescription() && config.getDeleteFrom() instanceof SpecimenOrObservationBase && config.getDeleteFrom().getId() == desc.getDescribedSpecimenOrObservation().getId()) || config.isDeleteFromEveryWhere()){
155 SpecimenOrObservationBase<?> specimen = desc.getDescribedSpecimenOrObservation();
156 updatedObject = specimen;
157 desc.removeElement(textData);
158 textData.removeMedia(media);
159 if (desc.getElements().isEmpty()){
160 specimen.removeDescription(desc);
161 }
162 } else {
163 result.setAbort();
164
165 }
166 }else if (description instanceof TaxonNameDescription){
167 TaxonNameDescription desc = HibernateProxyHelper.deproxy(description, TaxonNameDescription.class);
168
169 if (desc.getTaxonName() == null ){
170 continue;
171 } else if ((config.isDeleteFromDescription() && config.getDeleteFrom() instanceof TaxonName && config.getDeleteFrom().getId() == desc.getTaxonName().getId()) || config.isDeleteFromEveryWhere()){
172 TaxonName name= desc.getTaxonName();
173 updatedObject = name;
174 desc.removeElement(textData);
175 textData.removeMedia(media);
176 if (desc.getElements().isEmpty()){
177 name.removeDescription(desc);
178 }
179 } else {
180
181 result.setAbort();
182
183
184 }
185 }
186 }
187 } else if ((ref instanceof MediaSpecimen && config.getDeleteFrom().getId() == ref.getId() && config.getDeleteFrom() instanceof MediaSpecimen)
188 || (ref instanceof MediaSpecimen && config.isDeleteFromEveryWhere())){
189 MediaSpecimen mediaSpecimen = HibernateProxyHelper.deproxy(ref, MediaSpecimen.class);
190
191 mediaSpecimen.setMediaSpecimen(null);
192 updatedObject = mediaSpecimen;
193
194 }else if (ref instanceof MediaRepresentation){
195 continue;
196
197 }else {
198
199 result.setAbort();
200
201
202 }
203
204 }
205 if (result.isOk()){
206 dao.delete(media);
207 } else{
208 if (updatedObject instanceof
209 TaxonBase){
210 taxonService.update((TaxonBase)updatedObject);
211 result.addUpdatedObject(updatedObject);
212 }
213 if (updatedObject instanceof
214 TaxonName){
215 nameService.update((TaxonName)updatedObject);
216 }
217 if (updatedObject instanceof
218 SpecimenOrObservationBase){
219 specimenService.update((SpecimenOrObservationBase)updatedObject);
220 }
221 }
222 }
223 return result;
224 }
225
226
227 @Override
228 public DeleteResult isDeletable(UUID mediaUuid, DeleteConfiguratorBase config){
229 DeleteResult result = new DeleteResult();
230 Media media = this.load(mediaUuid);
231 Set<CdmBase> references = commonService.getReferencingObjectsForDeletion(media);
232 MediaDeletionConfigurator mediaConfig = (MediaDeletionConfigurator)config;
233 CdmBase deleteFrom = mediaConfig.getDeleteFrom();
234
235 if (mediaConfig.isDeleteFromEveryWhere()){
236 return result;
237 }
238 for (CdmBase ref: references){
239 String message = null;
240 if (ref instanceof MediaRepresentation){
241 continue;
242 }
243 if (ref instanceof TextData){
244 TextData textData = HibernateProxyHelper.deproxy(ref, TextData.class);
245 DescriptionBase description = HibernateProxyHelper.deproxy(textData.getInDescription(), DescriptionBase.class);
246
247 if (description instanceof TaxonDescription){
248 TaxonDescription desc = HibernateProxyHelper.deproxy(description, TaxonDescription.class);
249 if (desc.getTaxon() == null || (mediaConfig.isDeleteFromDescription() && (deleteFrom instanceof Taxon && ((Taxon)deleteFrom).getId() == desc.getTaxon().getId()))){
250 continue;
251 } else{
252 message = "The media can't be deleted from the database because it is referenced by another taxon. ("+desc.getTaxon().getTitleCache()+")";
253 result.setAbort();
254 }
255
256 } else if (description instanceof SpecimenDescription){
257 SpecimenDescription desc = HibernateProxyHelper.deproxy(description, SpecimenDescription.class);
258 if (desc.getDescribedSpecimenOrObservation() == null || (mediaConfig.isDeleteFromDescription() && (deleteFrom instanceof SpecimenOrObservationBase && ((SpecimenOrObservationBase)deleteFrom).getId() == desc.getDescribedSpecimenOrObservation().getId()))){
259 continue;
260 } else{
261 message = "The media can't be deleted from the database because it is referenced by another specimen or observation. ("+desc.getDescribedSpecimenOrObservation().getTitleCache()+")";
262 result.setAbort();
263 }
264 } else if (description instanceof TaxonNameDescription){
265 TaxonNameDescription desc = HibernateProxyHelper.deproxy(description, TaxonNameDescription.class);
266 if (desc.getTaxonName() == null || (mediaConfig.isDeleteFromDescription() && (deleteFrom instanceof TaxonName && ((TaxonName)deleteFrom).getId() == desc.getTaxonName().getId()))){
267 continue;
268 } else{
269 message = "The media can't be deleted from the database because it is referenced by another specimen or observation. ("+desc.getDescribedSpecimenOrObservation().getTitleCache()+")";
270 result.setAbort();
271 }
272 }
273
274 } else {
275 message = "The media can't be completely deleted because it is referenced by another " + ref.getUserFriendlyTypeName() ;
276 }
277 if (message != null){
278 result.addException(new ReferencedObjectUndeletableException(message));
279 result.addRelatedObject(ref);
280
281 }
282
283 }
284
285
286 return result;
287
288 }
289 }