fix #6174: isDeletable needs to be called with UUID and the objects is
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / MediaServiceImpl.java
index a11787ec97d874b0b2fe8acd92f7ac2c6ab62090..816c8435c2b1f2aa9cf344df1e21f5441ba36caa 100644 (file)
 // $Id$\r
 /**\r
  * Copyright (C) 2007 EDIT\r
- * European Distributed Institute of Taxonomy \r
+ * European Distributed Institute of Taxonomy\r
  * http://www.e-taxonomy.eu\r
- * \r
+ *\r
  * The contents of this file are subject to the Mozilla Public License Version 1.1\r
  * See LICENSE.TXT at the top of this package for the full license terms.\r
  */\r
 \r
 package eu.etaxonomy.cdm.api.service;\r
 \r
-import java.io.IOException;\r
-import java.net.HttpURLConnection;\r
-import java.net.MalformedURLException;\r
-import java.net.URI;\r
-import java.net.URL;\r
 import java.util.ArrayList;\r
 import java.util.List;\r
-import java.util.Map;\r
 import java.util.Set;\r
+import java.util.UUID;\r
 \r
-import org.apache.http.HttpException;\r
 import org.springframework.beans.factory.annotation.Autowired;\r
 import org.springframework.stereotype.Service;\r
-import org.springframework.transaction.annotation.Propagation;\r
 import org.springframework.transaction.annotation.Transactional;\r
 \r
+import eu.etaxonomy.cdm.api.service.config.DeleteConfiguratorBase;\r
+import eu.etaxonomy.cdm.api.service.config.MediaDeletionConfigurator;\r
+import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableException;\r
 import eu.etaxonomy.cdm.api.service.pager.Pager;\r
 import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;\r
-import eu.etaxonomy.cdm.common.IProgressMonitor;\r
-import eu.etaxonomy.cdm.common.media.ImageInfo;\r
+import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;\r
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+import eu.etaxonomy.cdm.model.description.DescriptionBase;\r
 import eu.etaxonomy.cdm.model.description.MediaKey;\r
+import eu.etaxonomy.cdm.model.description.SpecimenDescription;\r
+import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
+import eu.etaxonomy.cdm.model.description.TextData;\r
 import eu.etaxonomy.cdm.model.location.NamedArea;\r
 import eu.etaxonomy.cdm.model.media.Media;\r
+import eu.etaxonomy.cdm.model.media.MediaRepresentation;\r
 import eu.etaxonomy.cdm.model.media.Rights;\r
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;\r
 import eu.etaxonomy.cdm.model.taxon.Taxon;\r
 import eu.etaxonomy.cdm.persistence.dao.media.IMediaDao;\r
 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;\r
 \r
 @Service\r
-@Transactional(readOnly=true, propagation = Propagation.SUPPORTS)\r
+@Transactional(readOnly=true)\r
 public class MediaServiceImpl extends IdentifiableServiceBase<Media,IMediaDao> implements IMediaService {\r
 \r
-       @Autowired\r
+       @Override\r
+    @Autowired\r
        protected void setDao(IMediaDao dao) {\r
                this.dao = dao;\r
        }\r
 \r
-       public Pager<MediaKey> getMediaKeys(Set<Taxon> taxonomicScope, Set<NamedArea> geoScopes, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
+        @Autowired\r
+        private IDescriptionService descriptionService;\r
+\r
+       @Override\r
+    public Pager<MediaKey> getMediaKeys(Set<Taxon> taxonomicScope, Set<NamedArea> geoScopes, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
         Integer numberOfResults = dao.countMediaKeys(taxonomicScope, geoScopes);\r
-               \r
+\r
                List<MediaKey> results = new ArrayList<MediaKey>();\r
                if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)\r
-                       results = dao.getMediaKeys(taxonomicScope, geoScopes, pageSize, pageNumber, propertyPaths); \r
+                       results = dao.getMediaKeys(taxonomicScope, geoScopes, pageSize, pageNumber, propertyPaths);\r
                }\r
-               \r
+\r
                return new DefaultPagerImpl<MediaKey>(pageNumber, numberOfResults, pageSize, results);\r
        }\r
-       \r
-       public Pager<Rights> getRights(Media t, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
+\r
+       @Override\r
+    public Pager<Rights> getRights(Media t, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {\r
         Integer numberOfResults = dao.countRights(t);\r
-               \r
+\r
                List<Rights> results = new ArrayList<Rights>();\r
                if(numberOfResults > 0) { // no point checking again  //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)\r
-                       results = dao.getRights(t, pageSize, pageNumber,propertyPaths); \r
+                       results = dao.getRights(t, pageSize, pageNumber,propertyPaths);\r
                }\r
-               \r
-               return new DefaultPagerImpl<Rights>(pageNumber, numberOfResults, pageSize, results);\r
-       }\r
 \r
-       \r
-       @Deprecated // it does not make much sense to have this encapsulated in a service method, use ImageInfo directly\r
-       public ImageInfo getImageInfo(URI imageUri, Integer timeOut) throws IOException, HttpException{\r
-               ImageInfo imageInfo = ImageInfo.NewInstance(imageUri, timeOut);\r
-               imageInfo.readMetaData(timeOut);\r
-               \r
-               return imageInfo;\r
-       }\r
-       \r
-       @Deprecated // it does not make much sense to have this encapsulated in a service method, use ImageInfo directly\r
-       public Map<String,String> getImageMetaData(URI imageUri, Integer timeOut) throws IOException, HttpException{\r
-               \r
-               ImageInfo imageInfo = ImageInfo.NewInstance(imageUri, timeOut);         \r
-               \r
-               return imageInfo.getMetaData();\r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.api.service.IMediaService#getImageSize(java.net.URI, java.lang.Integer)\r
-        */\r
-       @Deprecated // it does not make much sense to have this encapsulated in a service method, use ImageInfo directly\r
-       public Integer getImageSize(URI imageUri, Integer timeOut) {\r
-               try {\r
-                       URL url = imageUri.toURL();\r
-                       HttpURLConnection.setFollowRedirects(false);\r
-                       \r
-                       HttpURLConnection connection = (HttpURLConnection) url.openConnection();\r
-                       \r
-                       return connection.getContentLength();\r
-                       \r
-               } catch (MalformedURLException e) {\r
-                       logger.trace("MalformedURLException when trying to get filesize for: " +imageUri);\r
-               } catch (IOException e) {\r
-                       logger.trace("IOException when trying to get filesize for: " +imageUri);\r
-               }\r
-               return null;\r
+               return new DefaultPagerImpl<Rights>(pageNumber, numberOfResults, pageSize, results);\r
        }\r
 \r
-\r
        /* (non-Javadoc)\r
         * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)\r
         */\r
        @Override\r
-       public void updateTitleCache(Class<? extends Media> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<Media> cacheStrategy, IProgressMonitor monitor) {\r
+       @Transactional(readOnly = false)\r
+    public void updateTitleCache(Class<? extends Media> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<Media> cacheStrategy, IProgressMonitor monitor) {\r
                //IIdentifiableEntityCacheStrategy<Media> cacheStrategy = MediaDefaultCacheStrategy();\r
                if (clazz == null){\r
                        clazz = Media.class;\r
                }\r
                super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);\r
        }\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.api.service.IMediaService#delete(java.util.UUID, eu.etaxonomy.cdm.api.service.config.MediaDeletionConfigurator)\r
+     */\r
+    @Override\r
+    @Transactional(readOnly=false)\r
+    public DeleteResult delete(UUID mediaUuid, MediaDeletionConfigurator config) {\r
+        DeleteResult result = new DeleteResult();\r
+        Media media = this.load(mediaUuid);\r
+\r
+        result = isDeletable(mediaUuid, config);\r
+\r
+        if (result.isOk()){\r
+            Set<CdmBase> references = commonService.getReferencingObjectsForDeletion(media);\r
+            String message = null;\r
+            for (CdmBase ref: references){\r
+                if (ref instanceof MediaRepresentation){\r
+                    MediaRepresentation mediaRep = HibernateProxyHelper.deproxy(ref, MediaRepresentation.class);\r
+                    media.removeRepresentation(mediaRep);\r
+                }\r
+                else if (ref instanceof TextData){\r
+\r
+                    TextData textData = HibernateProxyHelper.deproxy(ref, TextData.class);\r
+                    DescriptionBase description = HibernateProxyHelper.deproxy(textData.getInDescription(), DescriptionBase.class);\r
+\r
+                    if (description.isImageGallery()){\r
+                        if (description instanceof TaxonDescription){\r
+                            TaxonDescription desc = HibernateProxyHelper.deproxy(description, TaxonDescription.class);\r
+                            if (desc.getTaxon() == null ){\r
+                                continue;\r
+                            } else if ( config.isDeleteIfUsedInTaxonDescription()){\r
+                                Taxon taxon = desc.getTaxon();\r
+                                desc.removeElement(textData);\r
+                                textData.removeMedia(media);\r
+                                if (desc.getElements().isEmpty()){\r
+                                    taxon.removeDescription(desc);\r
+                                }\r
+                            }\r
+                        } else if (description instanceof SpecimenDescription){\r
+                            SpecimenDescription desc = HibernateProxyHelper.deproxy(description, SpecimenDescription.class);\r
+                            if (desc.getDescribedSpecimenOrObservation() == null || config.isDeleteIfUsedInSpecimenDescription()){\r
+                                continue;\r
+                            } else if (config.isDeleteIfUsedInSpecimenDescription()){\r
+                                SpecimenOrObservationBase<?> specimen = desc.getDescribedSpecimenOrObservation();\r
+                                desc.removeElement(textData);\r
+                                textData.removeMedia(media);\r
+                                if (desc.getElements().isEmpty()){\r
+                                    specimen.removeDescription(desc);\r
+                                }\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+\r
+            }\r
+            dao.delete(media);\r
+        }\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public DeleteResult isDeletable(UUID mediaUuid, DeleteConfiguratorBase config){\r
+        DeleteResult result = new DeleteResult();\r
+        Media media = this.load(mediaUuid);\r
+        Set<CdmBase> references = commonService.getReferencingObjectsForDeletion(media);\r
+        String message = null;\r
+        MediaDeletionConfigurator mediaConfig = (MediaDeletionConfigurator)config;\r
+        for (CdmBase ref: references){\r
+            if (ref instanceof TextData){\r
+                TextData textData = HibernateProxyHelper.deproxy(ref, TextData.class);\r
+                DescriptionBase description = textData.getInDescription();\r
+                if (description.isImageGallery()){\r
+                    if (description instanceof TaxonDescription){\r
+                        TaxonDescription desc = HibernateProxyHelper.deproxy(description, TaxonDescription.class);\r
+                        if (desc.getTaxon() == null || mediaConfig.isDeleteIfUsedInTaxonDescription()){\r
+                            continue;\r
+                        } else{\r
+                            message = "The media can't be deleted because it is referenced by a taxon. ("+desc.getTaxon().getTitleCache()+")";\r
+                        }\r
+\r
+                    } else if (description instanceof SpecimenDescription){\r
+                        SpecimenDescription desc = HibernateProxyHelper.deproxy(description, SpecimenDescription.class);\r
+                        if (desc.getDescribedSpecimenOrObservation() == null || mediaConfig.isDeleteIfUsedInSpecimenDescription()){\r
+                            continue;\r
+                        } else{\r
+                            message = "The media can't be deleted because it is referenced by a specimen or observation. ("+desc.getDescribedSpecimenOrObservation().getTitleCache()+")";\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            if (message != null){\r
+                result.addException(new ReferencedObjectUndeletableException(message));\r
+                result.addRelatedObject(ref);\r
+                result.setAbort();\r
+            }\r
+\r
+        }\r
+\r
+\r
+        return result;\r
+\r
+    }\r
 }\r