2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.api
.service
;
12 import java
.util
.ArrayList
;
13 import java
.util
.List
;
15 import java
.util
.UUID
;
17 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
18 import org
.springframework
.stereotype
.Service
;
19 import org
.springframework
.transaction
.annotation
.Transactional
;
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
.common
.ICdmBase
;
30 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionBase
;
31 import eu
.etaxonomy
.cdm
.model
.description
.IDescribable
;
32 import eu
.etaxonomy
.cdm
.model
.description
.MediaKey
;
33 import eu
.etaxonomy
.cdm
.model
.description
.SpecimenDescription
;
34 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
35 import eu
.etaxonomy
.cdm
.model
.description
.TaxonNameDescription
;
36 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
37 import eu
.etaxonomy
.cdm
.model
.location
.NamedArea
;
38 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
39 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentation
;
40 import eu
.etaxonomy
.cdm
.model
.media
.Rights
;
41 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
42 import eu
.etaxonomy
.cdm
.model
.occurrence
.MediaSpecimen
;
43 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
44 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
45 import eu
.etaxonomy
.cdm
.persistence
.dao
.media
.IMediaDao
;
46 import eu
.etaxonomy
.cdm
.strategy
.cache
.common
.IIdentifiableEntityCacheStrategy
;
49 @Transactional(readOnly
=true)
50 public class MediaServiceImpl
extends IdentifiableServiceBase
<Media
,IMediaDao
> implements IMediaService
{
54 protected void setDao(IMediaDao dao
) {
59 private IOccurrenceService specimenService
;
61 private ITaxonService taxonService
;
63 private INameService nameService
;
67 public Pager
<MediaKey
> getMediaKeys(Set
<Taxon
> taxonomicScope
, Set
<NamedArea
> geoScopes
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
68 long numberOfResults
= dao
.countMediaKeys(taxonomicScope
, geoScopes
);
70 List
<MediaKey
> results
= new ArrayList
<>();
71 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
72 results
= dao
.getMediaKeys(taxonomicScope
, geoScopes
, pageSize
, pageNumber
, propertyPaths
);
75 return new DefaultPagerImpl
<>(pageNumber
, numberOfResults
, pageSize
, results
);
79 public Pager
<Rights
> getRights(Media t
, Integer pageSize
, Integer pageNumber
, List
<String
> propertyPaths
) {
80 long numberOfResults
= dao
.countRights(t
);
82 List
<Rights
> results
= new ArrayList
<>();
83 if(numberOfResults
> 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
84 results
= dao
.getRights(t
, pageSize
, pageNumber
,propertyPaths
);
87 return new DefaultPagerImpl
<>(pageNumber
, numberOfResults
, pageSize
, results
);
91 @Transactional(readOnly
= false)
92 public UpdateResult
updateCaches(Class
<?
extends Media
> clazz
, Integer stepSize
, IIdentifiableEntityCacheStrategy
<Media
> cacheStrategy
, IProgressMonitor monitor
) {
96 return super.updateCachesImpl(clazz
, stepSize
, cacheStrategy
, monitor
);
100 @Transactional(readOnly
=false)
101 public DeleteResult
delete(UUID mediaUuid
, MediaDeletionConfigurator config
) {
102 DeleteResult result
= new DeleteResult();
103 Media media
= this.load(mediaUuid
);
107 result
= isDeletable(mediaUuid
, config
);
109 Set
<CdmBase
> references
= commonService
.getReferencingObjectsForDeletion(media
);
110 for (CdmBase ref
: references
){
112 IDescribable
<?
> updatedObject
= null;
113 IService
<ICdmBase
> service
= null;
114 if (ref
instanceof TextData
){
116 TextData textData
= HibernateProxyHelper
.deproxy(ref
, TextData
.class);
117 DescriptionBase
<?
> description
= HibernateProxyHelper
.deproxy(textData
.getInDescription(), DescriptionBase
.class);
119 IDescribable
<?
> objectToUpdate
= null;
120 boolean deleteIsMatchingInstance
= false;
121 if (description
instanceof TaxonDescription
){
122 objectToUpdate
= ((TaxonDescription
)description
).getTaxon();
123 deleteIsMatchingInstance
= config
.getDeleteFrom() instanceof Taxon
;
124 service
= (IService
)taxonService
;
125 }else if (description
instanceof SpecimenDescription
){
126 objectToUpdate
= ((SpecimenDescription
)description
).getDescribedSpecimenOrObservation();
127 deleteIsMatchingInstance
= config
.getDeleteFrom() instanceof SpecimenOrObservationBase
;
128 service
= (IService
)specimenService
;
129 }else if (description
instanceof TaxonNameDescription
){
130 objectToUpdate
= ((TaxonNameDescription
)description
).getTaxonName();
131 deleteIsMatchingInstance
= config
.getDeleteFrom() instanceof TaxonName
;
132 service
= (IService
)nameService
;
134 throw new RuntimeException("Unsupported DescriptionBase class");
137 if (objectToUpdate
== null ){
139 } else if ( (config
.isDeleteFromDescription() && deleteIsMatchingInstance
&&
140 config
.getDeleteFrom().getId() == objectToUpdate
.getId())
141 || config
.isDeleteFromEveryWhere()){
142 updatedObject
= handleDeleteMedia(media
, textData
, description
,
143 (IDescribable
)objectToUpdate
);
145 // this should not be happen, because it is not deletable. see isDeletable
149 // } else if (ref instanceof MediaSpecimen && config.getDeleteFrom().getId() == ref.getId() && config.getDeleteFrom() instanceof MediaSpecimen){
150 // MediaSpecimen mediaSpecimen = HibernateProxyHelper.deproxy(ref, MediaSpecimen.class);
151 // mediaSpecimen.setMediaSpecimen(null);
152 // updatedObject = mediaSpecimen;
153 // service = (IService)specimenService;
154 }else if (ref
instanceof MediaRepresentation
){
160 if (updatedObject
!= null){
161 service
.update(updatedObject
); //service should always be != null if updatedObject != null
162 result
.addUpdatedObject((CdmBase
)updatedObject
);
167 result
.addDeletedObject(media
);
180 private IDescribable
<DescriptionBase
<?
>> handleDeleteMedia(Media media
, TextData textData
,
181 DescriptionBase
<?
> desc
, IDescribable
<DescriptionBase
<?
>> describable
) {
182 while(textData
.getMedia().contains(media
)){
183 textData
.removeMedia(media
);
185 //if the textData contains text it should not be deleted
186 if (textData
.getMedia().isEmpty() && textData
.getMultilanguageText().isEmpty()){
187 desc
.removeElement(textData
);
189 if (desc
.getElements().isEmpty()){
190 describable
.removeDescription(desc
);
197 public DeleteResult
isDeletable(UUID mediaUuid
, DeleteConfiguratorBase config
){
198 DeleteResult result
= new DeleteResult();
199 Media media
= this.load(mediaUuid
);
200 Set
<CdmBase
> references
= commonService
.getReferencingObjectsForDeletion(media
);
201 MediaDeletionConfigurator mediaConfig
= (MediaDeletionConfigurator
)config
;
202 CdmBase deleteFrom
= mediaConfig
.getDeleteFrom();
204 if (mediaConfig
.isDeleteFromEveryWhere()){
207 for (CdmBase ref
: references
){
208 String message
= null;
209 if (ref
instanceof MediaRepresentation
){
212 if (ref
instanceof TextData
){
213 TextData textData
= HibernateProxyHelper
.deproxy(ref
, TextData
.class);
214 DescriptionBase description
= HibernateProxyHelper
.deproxy(textData
.getInDescription(), DescriptionBase
.class);
216 if (description
instanceof TaxonDescription
){
217 TaxonDescription desc
= HibernateProxyHelper
.deproxy(description
, TaxonDescription
.class);
218 if (desc
.getTaxon() == null || (mediaConfig
.isDeleteFromDescription() && (deleteFrom
instanceof Taxon
&& ((Taxon
)deleteFrom
).getId() == desc
.getTaxon().getId()))){
221 message
= "The media can't be deleted from the database because it is referenced by a taxon. ("+desc
.getTaxon().getTitleCache()+")";
225 } else if (description
instanceof SpecimenDescription
){
226 SpecimenDescription desc
= HibernateProxyHelper
.deproxy(description
, SpecimenDescription
.class);
227 if (desc
.getDescribedSpecimenOrObservation() == null || (mediaConfig
.isDeleteFromDescription() && (deleteFrom
instanceof SpecimenOrObservationBase
&& ((SpecimenOrObservationBase
)deleteFrom
).getId() == desc
.getDescribedSpecimenOrObservation().getId()))){
230 message
= "The media can't be deleted from the database because it is referenced by a specimen or observation. ("+desc
.getDescribedSpecimenOrObservation().getTitleCache()+")";
233 } else if (description
instanceof TaxonNameDescription
){
234 TaxonNameDescription desc
= HibernateProxyHelper
.deproxy(description
, TaxonNameDescription
.class);
235 if (desc
.getTaxonName() == null || (mediaConfig
.isDeleteFromDescription() && (deleteFrom
instanceof TaxonName
&& ((TaxonName
)deleteFrom
).getId() == desc
.getTaxonName().getId()))){
238 message
= "The media can't be deleted from the database because it is referenced by a scientific name. ("+desc
.getTaxonName().getTitleCache()+")";
243 }if (ref
instanceof MediaSpecimen
){
244 message
= "The media can't be deleted from the database because it is referenced by a mediaspecimen. ("+((MediaSpecimen
)ref
).getTitleCache()+")";
247 message
= "The media can't be completely deleted because it is referenced by another " + ref
.getUserFriendlyTypeName() ;
250 if (message
!= null){
251 result
.addException(new ReferencedObjectUndeletableException(message
));
252 result
.addRelatedObject(ref
);