fix #6459 Implement deduplication for IntextReferences
authorAndreas Müller <a.mueller@bgbm.org>
Thu, 9 Mar 2017 15:19:42 +0000 (16:19 +0100)
committerAndreas Müller <a.mueller@bgbm.org>
Thu, 9 Mar 2017 15:20:12 +0000 (16:20 +0100)
14 files changed:
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/markup/MarkupImportBase.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/agent/AgentBase.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/Annotation.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/IIntextReferencable.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/IIntextReferenceTarget.java [new file with mode: 0644]
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/IntextReference.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/LanguageString.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/media/Media.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/name/TaxonNameBase.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/reference/Reference.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/taxon/TaxonBase.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/database/data/FullCoverageDataGenerator.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/DeduplicationHelper.java
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/CdmGenericDaoImplTest.java

index d23aea6722ceac7fa4a219da05368c556055c115..5584572477829258269954f5b7e56846cb6ff110 100644 (file)
@@ -1883,7 +1883,7 @@ public abstract class MarkupImportBase  {
        private String handleInLineReference(MarkupImportState state,XMLEventReader reader, XMLEvent parentEvent, MarkupNomenclatureImport nomenclatureImport)throws XMLStreamException {
                Reference reference = nomenclatureImport.handleReference(state, reader, parentEvent);
                fireWarningEvent("Check correct usage of inline reference", parentEvent, 3);
-               IntextReference intext = IntextReference.NewReferenceInstance(reference, null, 0, 0);
+               IntextReference intext = IntextReference.NewInstance(reference, null, 0, 0);
                save(reference, state);
                return intext.toInlineString(reference.getTitleCache());
        }
@@ -1932,7 +1932,7 @@ public abstract class MarkupImportBase  {
                                && !isStartingElement(next, SUB_HEADING)){
                            for (LabeledReference labeledRef : currentReferences.content){
                                if (labeledRef.ref != null){
-                                   IntextReference intext = IntextReference.NewReferenceInstance(labeledRef.ref, null, 0, 0);
+                                   IntextReference intext = IntextReference.NewInstance(labeledRef.ref, null, 0, 0);
                                    inlineReferences.add(intext);
                                    text += intext.toInlineString(labeledRef.label);
                                }else{
index 43a431ba6d77cf5a3862d7b98dffa2c24d78e408..fed251e85852b47436dc6804dcacd1db0e405a11 100644 (file)
@@ -28,6 +28,7 @@ import org.hibernate.annotations.Index;
 import org.hibernate.annotations.Table;
 import org.hibernate.envers.Audited;
 
+import eu.etaxonomy.cdm.model.common.IIntextReferenceTarget;
 import eu.etaxonomy.cdm.model.location.Country;
 import eu.etaxonomy.cdm.model.location.Point;
 import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
@@ -56,7 +57,9 @@ import eu.etaxonomy.cdm.strategy.merge.MergeMode;
 @Entity
 @Audited
 @Table(appliesTo="AgentBase", indexes = { @Index(name = "agentTitleCacheIndex", columnNames = { "titleCache" }) })
-public abstract class AgentBase<S extends IIdentifiableEntityCacheStrategy<? extends AgentBase<S>>> extends IdentifiableMediaEntity<S> implements IMergable, IMatchable, Cloneable{
+public abstract class AgentBase<S extends IIdentifiableEntityCacheStrategy<? extends AgentBase<S>>>
+        extends IdentifiableMediaEntity<S>
+        implements IMergable, IMatchable, IIntextReferenceTarget, Cloneable{
        private static final long serialVersionUID = 7732768617469448829L;
        @SuppressWarnings("unused")
        private static final Logger logger = Logger.getLogger(AgentBase.class);
index d01fdb71fdd0563def992f2de72c029fe14d53b5..278233a293868744d6b42448ec162266eb7da8d9 100644 (file)
@@ -157,10 +157,11 @@ public class Annotation extends LanguageStringBase implements Cloneable, IIntext
     public Set<IntextReference> getIntextReferences(){
                return this.intextReferences;
        }
+
        @Override
     public void addIntextReference(IntextReference intextReference){
                if (intextReference != null){
-                       intextReference.setAnnotation(this);
+                       intextReference.setReferencedEntity(this);
                        getIntextReferences().add(intextReference);
                }
        }
@@ -169,7 +170,7 @@ public class Annotation extends LanguageStringBase implements Cloneable, IIntext
     public void removeIntextReference(IntextReference intextReference){
                if(getIntextReferences().contains(intextReference)) {
                        getIntextReferences().remove(intextReference);
-                       intextReference.setAnnotation((Annotation)null);
+                       intextReference.setReferencedEntity((Annotation)null);
                }
        }
 
index ce8f4586b7a7b0e4f54538b11ad4503a2fd0d4a8..e93cc182a4c6eb69c8a895847831e587f4eac581 100644 (file)
@@ -4,11 +4,24 @@ import java.util.Set;
 \r
 public interface IIntextReferencable {\r
 \r
-       \r
+\r
        //*************** INTEXT REFERENCE **********************************************\r
-       \r
+\r
        public Set<IntextReference> getIntextReferences();\r
+\r
        public void addIntextReference(IntextReference intextReference);\r
-       \r
+\r
        public void removeIntextReference(IntextReference intextReference);\r
+\r
+       /**\r
+        * Returns the referenced text\r
+     * @return the referenced text\r
+     */\r
+    public String getText();\r
+\r
+    /**\r
+     * Sets the referenced text.\r
+     * @param text the new referenced text\r
+     */\r
+    public void setText(String text);\r
 }\r
diff --git a/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/IIntextReferenceTarget.java b/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/IIntextReferenceTarget.java
new file mode 100644 (file)
index 0000000..4495d45
--- /dev/null
@@ -0,0 +1,21 @@
+/**
+* Copyright (C) 2017 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.model.common;
+
+/**
+ * Interface to flag those classes available as targets of
+ * an {@link IntextReference}.
+ *
+ * @author a.mueller
+ * @date 08.03.2017
+ *
+ */
+public interface IIntextReferenceTarget extends ICdmBase{
+
+}
index 5e38a451c56f4ebd76d09c1e16f8ed5ecd54dc5d..bf9f6d412b7384247d7e1f9403e4a7d64a15440a 100644 (file)
@@ -136,29 +136,56 @@ public class IntextReference extends VersionableEntity {
 \r
 // ***************** FACTORY METHOD ***********************************\r
 \r
-       public static IntextReference NewTaxonNameInstance(TaxonNameBase<?,?> taxonName, LanguageStringBase languageString, int start, int end){\r
-               return new IntextReference(taxonName, null, null, null, null, null, languageString, start, end);\r
-       }\r
-\r
-       public static IntextReference NewTaxonInstance(TaxonBase<?> taxon, LanguageStringBase languageString, int start, int end){\r
-               return new IntextReference(null, taxon, null, null, null, null, languageString, start, end);\r
-       }\r
-\r
-       public static IntextReference NewOccurrenceInstance(SpecimenOrObservationBase<?> occurrence, LanguageStringBase languageString, int start, int end){\r
-               return new IntextReference(null, null, occurrence, null, null, null, languageString, start, end);\r
-       }\r
-\r
-       public static IntextReference NewAgentInstance(AgentBase<?> agent, LanguageStringBase languageString, int start, int end){\r
-               return new IntextReference(null, null, null, agent, null, null, languageString, start, end);\r
-       }\r
+    public static IntextReference NewInstance(IIntextReferenceTarget target,\r
+            IIntextReferencable referencedEntity, int start, int end){\r
+        IntextReference result = new IntextReference(target, referencedEntity, start, end);\r
+        return result;\r
+    }\r
 \r
-       public static IntextReference NewReferenceInstance(Reference reference, LanguageStringBase languageString, int start, int end){\r
-               return new IntextReference(null, null, null, null, reference, null, languageString, start, end);\r
-       }\r
+//     public static IntextReference NewTaxonNameInstance(TaxonNameBase<?,?> taxonName, LanguageStringBase languageString, int start, int end){\r
+//             return new IntextReference(taxonName, null, null, null, null, null, languageString, start, end);\r
+//     }\r
+//\r
+//     public static IntextReference NewTaxonInstance(TaxonBase<?> taxon, LanguageStringBase languageString, int start, int end){\r
+//             return new IntextReference(null, taxon, null, null, null, null, languageString, start, end);\r
+//     }\r
+//\r
+//     public static IntextReference NewOccurrenceInstance(SpecimenOrObservationBase<?> occurrence, LanguageStringBase languageString, int start, int end){\r
+//             return new IntextReference(null, null, occurrence, null, null, null, languageString, start, end);\r
+//     }\r
+//\r
+//     public static IntextReference NewAgentInstance(AgentBase<?> agent, LanguageStringBase languageString, int start, int end){\r
+//             return new IntextReference(null, null, null, agent, null, null, languageString, start, end);\r
+//     }\r
+//\r
+//     public static IntextReference NewReferenceInstance(Reference reference, LanguageStringBase languageString, int start, int end){\r
+//             return new IntextReference(null, null, null, null, reference, null, languageString, start, end);\r
+//     }\r
+//\r
+//     public static IntextReference NewMediaInstance(Media media, LanguageStringBase languageString, int start, int end){\r
+//             return new IntextReference(null, null, null, null, null, media, languageString, start, end);\r
+//     }\r
+\r
+       public static LanguageString NewReferencedLanguageString(IIntextReferenceTarget target, String pre, String middle, String post, Language language){\r
+        LanguageString result = LanguageString.NewInstance(null, language);\r
+        IntextReference intextReference = IntextReference.NewInstance(target, result, 0, 0);\r
+           result.addIntextReference(intextReference);\r
+           result.setText(pre + intextReference.toInlineString(middle) + post);\r
+        return result;\r
+    }\r
 \r
-       public static IntextReference NewMediaInstance(Media media, LanguageStringBase languageString, int start, int end){\r
-               return new IntextReference(null, null, null, null, null, media, languageString, start, end);\r
-       }\r
+    public static LanguageString NewReferencedLanguageString(IIntextReferenceTarget target, String text, int start, int end, Language language){\r
+        if (start < 0 || end < 0 || start > end || end > text.length()){\r
+            throw new IndexOutOfBoundsException("Start and end must be within bounds");\r
+        }\r
+        LanguageString result = LanguageString.NewInstance(text, language);\r
+        IntextReference intextReference = IntextReference.NewInstance(target, result, start, end);\r
+        result.addIntextReference(intextReference);\r
+        String intext = text.substring(0, start) +\r
+                intextReference.toInlineString(text.substring(start, end)) + text.substring(end);\r
+        result.setText(intext);\r
+        return result;\r
+    }\r
 \r
 //********************** CONSTRUCTOR ********************************************/\r
 \r
@@ -168,29 +195,38 @@ public class IntextReference extends VersionableEntity {
        @Deprecated //for hibernate use only\r
        private IntextReference(){}\r
 \r
-       private IntextReference(TaxonNameBase<?, ?> taxonName, TaxonBase<?> taxon,\r
-                               SpecimenOrObservationBase<?> occurrence, AgentBase<?> agent,\r
-                               Reference reference, Media media, LanguageStringBase languageString, int start, int end) {\r
-                       super();\r
-                       this.taxonName = taxonName;\r
-                       this.taxon = taxon;\r
-                       this.occurrence = occurrence;\r
-                       this.agent = agent;\r
-                       this.reference = reference;\r
-                       this.media = media;\r
-                       if (languageString != null && languageString.isInstanceOf(LanguageString.class)){\r
-                               this.languageString = CdmBase.deproxy(languageString, LanguageString.class);\r
-                               this.languageString.addIntextReference(this);\r
-                       }else if (languageString != null && languageString.isInstanceOf(Annotation.class)){\r
-                               this.annotation = CdmBase.deproxy(languageString, Annotation.class);\r
-                               this.annotation.addIntextReference(this);\r
-                       }\r
-                       this.startPos = start;\r
-                       this.endPos = end;\r
-       }\r
+//     private IntextReference(TaxonNameBase<?, ?> taxonName, TaxonBase<?> taxon,\r
+//                             SpecimenOrObservationBase<?> occurrence, AgentBase<?> agent,\r
+//                             Reference reference, Media media, LanguageStringBase languageString, int start, int end) {\r
+//                     super();\r
+//                     this.taxonName = taxonName;\r
+//                     this.taxon = taxon;\r
+//                     this.occurrence = occurrence;\r
+//                     this.agent = agent;\r
+//                     this.reference = reference;\r
+//                     this.media = media;\r
+//                     if (languageString != null && languageString.isInstanceOf(LanguageString.class)){\r
+//                             this.languageString = CdmBase.deproxy(languageString, LanguageString.class);\r
+//                             this.languageString.addIntextReference(this);\r
+//                     }else if (languageString != null && languageString.isInstanceOf(Annotation.class)){\r
+//                             this.annotation = CdmBase.deproxy(languageString, Annotation.class);\r
+//                             this.annotation.addIntextReference(this);\r
+//                     }\r
+//                     this.startPos = start;\r
+//                     this.endPos = end;\r
+//     }\r
+\r
+          private IntextReference(IIntextReferenceTarget target, IIntextReferencable referencedEntity, int start, int end) {\r
+           super();\r
+           setTarget(target);\r
+           setReferencedEntity(referencedEntity);\r
+\r
+           this.startPos = start;\r
+           this.endPos = end;\r
+   }\r
 \r
 \r
-   private CDM_INTEXT_CLASS myClass(){\r
+    private CDM_INTEXT_CLASS myClass(){\r
         if (agent != null){\r
             return CDM_INTEXT_CLASS.AGENT;\r
         }else if (media != null){\r
@@ -208,7 +244,15 @@ public class IntextReference extends VersionableEntity {
         }\r
     }\r
 \r
-   private IdentifiableEntity<?> myEntity(){\r
+// ****************    GETTER / SETTER ******************************************/\r
+\r
+   /**\r
+    * Returns the target object. Throws an {@link IllegalStateException} if no target\r
+    * is defined.\r
+    *\r
+    * @return\r
+    */\r
+   public IIntextReferenceTarget getTarget() {\r
        if (agent != null){\r
            return agent;\r
        }else if (media != null){\r
@@ -226,67 +270,121 @@ public class IntextReference extends VersionableEntity {
        }\r
    }\r
 \r
-// ****************    GETTER / SETTER ******************************************/\r
-\r
-       public TaxonNameBase<?, ?> getTaxonName() {\r
-               return taxonName;\r
-       }\r
-       public void setTaxonName(TaxonNameBase<?, ?> taxonName) {\r
-               this.taxonName = taxonName;\r
-       }\r
-\r
-\r
-       public TaxonBase<?> getTaxon() {\r
-               return taxon;\r
-       }\r
-       public void setTaxon(TaxonBase<?> taxon) {\r
-               this.taxon = taxon;\r
-       }\r
-\r
-       public SpecimenOrObservationBase<?> getOccurrence() {\r
-               return occurrence;\r
-       }\r
-       public void setOccurrence(SpecimenOrObservationBase<?> occurrence) {\r
-               this.occurrence = occurrence;\r
-       }\r
-\r
-       public AgentBase<?> getAgent() {\r
-               return agent;\r
-       }\r
-       public void setAgent(AgentBase<?> agent) {\r
-               this.agent = agent;\r
-       }\r
-\r
-       public Reference getReference() {\r
-               return reference;\r
-       }\r
-       public void setReference(Reference reference) {\r
-               this.reference = reference;\r
-       }\r
-\r
-\r
-\r
-       public Media getMedia() {\r
-               return media;\r
-       }\r
-       public void setMedia(Media media) {\r
-               this.media = media;\r
-       }\r
+   /**\r
+     * @param target\r
+     */\r
+    private void setTarget(IIntextReferenceTarget target) {\r
+        target = CdmBase.deproxy(target);\r
+        if (target instanceof TaxonNameBase){\r
+            this.taxonName = (TaxonNameBase<?,?>)target;\r
+        }else if (target instanceof TaxonBase){\r
+            this.taxon = (TaxonBase<?>)target;\r
+        }else if (target instanceof SpecimenOrObservationBase){\r
+            this.occurrence = (SpecimenOrObservationBase<?>)target;\r
+        }else if (target instanceof AgentBase){\r
+            this.agent = (AgentBase<?>)target;\r
+        }else if (target instanceof Reference){\r
+            this.reference = (Reference)target;\r
+        }else if (target instanceof Media){\r
+            this.media = (Media)target;\r
+        }else{\r
+            throw new IllegalArgumentException("Target entity not yet handled: " + target.getClass().getName());\r
+        }\r
+    }\r
 \r
-       public LanguageString getLanguageString() {\r
-               return languageString;\r
-       }\r
-       public void setLanguageString(LanguageString languageString) {\r
-               this.languageString = languageString;\r
-       }\r
+   public IIntextReferencable getReferencedEntity() {\r
+       if (languageString != null){\r
+           return languageString;\r
+       }else if (annotation != null){\r
+           return annotation;\r
+       }else{\r
+           return null;\r
+       }\r
+   }\r
 \r
-       public Annotation getAnnotation() {\r
-               return annotation;\r
-       }\r
+   /**\r
+    * @param referencedEntity\r
+    */\r
+   public void setReferencedEntity(IIntextReferencable referencedEntity) {\r
+       if (referencedEntity == null){\r
+           this.annotation = null;\r
+           this.languageString = null;\r
+       }else if (this.getReferencedEntity() == referencedEntity){\r
+           //do nothing\r
+       }else{\r
+           referencedEntity = CdmBase.deproxy(referencedEntity);\r
+           if (referencedEntity instanceof LanguageString){\r
+               this.languageString = (LanguageString)referencedEntity;\r
+               this.annotation = null;\r
+           }else if (referencedEntity instanceof Annotation){\r
+               this.annotation = (Annotation)referencedEntity;\r
+               this.languageString = null;\r
+           }else{\r
+               throw new IllegalArgumentException("Referenced entity type not yet supported: " + referencedEntity.getClass().getName());\r
+           }\r
+           if (!referencedEntity.getIntextReferences().contains(this)){\r
+               referencedEntity.addIntextReference(this);\r
+           }\r
+       }\r
+   }\r
 \r
-       public void setAnnotation(Annotation annotation) {\r
-               this.annotation = annotation;\r
-       }\r
+//     public TaxonNameBase<?, ?> getTaxonName() {\r
+//             return taxonName;\r
+//     }\r
+//     public void setTaxonName(TaxonNameBase<?, ?> taxonName) {\r
+//             this.taxonName = taxonName;\r
+//     }\r
+//\r
+//\r
+//     public TaxonBase<?> getTaxon() {\r
+//             return taxon;\r
+//     }\r
+//     public void setTaxon(TaxonBase<?> taxon) {\r
+//             this.taxon = taxon;\r
+//     }\r
+//\r
+//     public SpecimenOrObservationBase<?> getOccurrence() {\r
+//             return occurrence;\r
+//     }\r
+//     public void setOccurrence(SpecimenOrObservationBase<?> occurrence) {\r
+//             this.occurrence = occurrence;\r
+//     }\r
+//\r
+//     public AgentBase<?> getAgent() {\r
+//             return agent;\r
+//     }\r
+//     public void setAgent(AgentBase<?> agent) {\r
+//             this.agent = agent;\r
+//     }\r
+//\r
+//     public Reference getReference() {\r
+//             return reference;\r
+//     }\r
+//     public void setReference(Reference reference) {\r
+//             this.reference = reference;\r
+//     }\r
+//\r
+//     public Media getMedia() {\r
+//             return media;\r
+//     }\r
+//     public void setMedia(Media media) {\r
+//             this.media = media;\r
+//     }\r
+\r
+//     public LanguageString getLanguageString() {\r
+//             return languageString;\r
+//     }\r
+//     protected void setLanguageString(LanguageString languageString) {\r
+//             this.languageString = languageString;\r
+//     }\r
+//\r
+//     public Annotation getAnnotation() {\r
+//             return annotation;\r
+//     }\r
+//\r
+//     public void setAnnotation(Annotation annotation) {\r
+//             this.annotation = annotation;\r
+//     }\r
 \r
        public int getStartPos() {\r
                return startPos;\r
@@ -305,7 +403,7 @@ public class IntextReference extends VersionableEntity {
        private static final String CDM_PREFIX = "cdm:";\r
        public String toInlineString(String innerText){\r
            String tag = CDM_PREFIX + myClass().tag();\r
-           IdentifiableEntity<?> entity = myEntity();\r
+           IIntextReferenceTarget entity = getTarget();\r
            String attributes = " cdmId='" + entity.getUuid() + "' intextId='" + this.getUuid() + "'" + otherAttributes(entity);\r
            String result;\r
            if (StringUtils.isNotEmpty(innerText)){\r
@@ -321,7 +419,7 @@ public class IntextReference extends VersionableEntity {
      * @param entity\r
      * @return\r
      */\r
-    private String otherAttributes(IdentifiableEntity<?> entity) {\r
+    private String otherAttributes(IIntextReferenceTarget entity) {\r
         return "";\r
     }\r
 \r
index c43154a9c201a280971f361a15f14d12372f29bd..46c5bffd10ee296c72e35a0851087e221bfab297 100644 (file)
@@ -63,10 +63,30 @@ public class LanguageString  extends LanguageStringBase implements Cloneable, II
     private void setIntextReferences(Set<IntextReference> intextReferences){
         this.intextReferences = intextReferences;
     }
+
+
+    public IntextReference addIntextReference(IIntextReferenceTarget target, String start, String inner, String end){
+        IntextReference intextReference = IntextReference.NewInstance(target, this, 0, 0);
+        setText(start + intextReference.toInlineString(inner) + end);
+        getIntextReferences().add(intextReference);
+        return intextReference;
+    }
+    public IntextReference addIntextReference(IIntextReferenceTarget target, int start, int end){
+        if (start < 0 || end < 0 || start > end || end > text.length()){
+            throw new IndexOutOfBoundsException("Start and end must be within bounds");
+        }
+        IntextReference intextReference = IntextReference.NewInstance(target, this, 0, 0);
+        String text = this.getText();
+        setText(text.substring(0, start) + intextReference.toInlineString(text.substring(start,end))
+            + text.substring(end));
+        getIntextReferences().add(intextReference);
+        return intextReference;
+    }
+
        @Override
     public void addIntextReference(IntextReference intextReference){
                if (intextReference != null){
-                       intextReference.setLanguageString(this);
+                       intextReference.setReferencedEntity(this);
                        getIntextReferences().add(intextReference);
                }
        }
@@ -75,7 +95,7 @@ public class LanguageString  extends LanguageStringBase implements Cloneable, II
     public void removeIntextReference(IntextReference intextReference){
                if(getIntextReferences().contains(intextReference)) {
                        getIntextReferences().remove(intextReference);
-                       intextReference.setLanguageString(null);
+                       intextReference.setReferencedEntity(null);
                }
        }
 
index a54d97f0044e50e77f58c7cf79b607f466dd5c3a..c6a682677f145dc0b4955441c8f56ff7236ae1bc 100644 (file)
@@ -49,6 +49,7 @@ import org.joda.time.DateTime;
 import eu.etaxonomy.cdm.jaxb.DateTimeAdapter;
 import eu.etaxonomy.cdm.jaxb.MultilanguageTextAdapter;
 import eu.etaxonomy.cdm.model.agent.AgentBase;
+import eu.etaxonomy.cdm.model.common.IIntextReferenceTarget;
 import eu.etaxonomy.cdm.model.common.IMultiLanguageTextHolder;
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
 import eu.etaxonomy.cdm.model.common.Language;
@@ -83,7 +84,8 @@ import eu.etaxonomy.cdm.validation.Level2;
 //@Indexed
 @Audited
 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-public class Media extends IdentifiableEntity<IIdentifiableEntityCacheStrategy> implements Cloneable, IMultiLanguageTextHolder {
+public class Media extends IdentifiableEntity<IIdentifiableEntityCacheStrategy>
+        implements IMultiLanguageTextHolder, IIntextReferenceTarget, Cloneable {
     private static final long serialVersionUID = -1927421567263473658L;
     @SuppressWarnings("unused")
     private static final Logger logger = Logger.getLogger(Media.class);
index 6ae408d2cae7e81b7d1d2f1e49aad59d05f19593..65e882be69c65668e5265b08b616972ae9644cf2 100644 (file)
@@ -65,6 +65,7 @@ import eu.etaxonomy.cdm.common.UTF8;
 import eu.etaxonomy.cdm.model.agent.INomenclaturalAuthor;
 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
 import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.common.IIntextReferenceTarget;
 import eu.etaxonomy.cdm.model.common.IParsable;
 import eu.etaxonomy.cdm.model.common.IRelated;
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
@@ -167,7 +168,7 @@ public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INam
             extends IdentifiableEntity<S>
             implements ITaxonNameBase, INonViralName, IViralName, IBacterialName, IZoologicalName,
                 IBotanicalName, ICultivarPlantName,
-                IParsable, IRelated, IMatchable, Cloneable {
+                IParsable, IRelated, IMatchable, IIntextReferenceTarget, Cloneable {
 
     private static final long serialVersionUID = -791164269603409712L;
     private static final Logger logger = Logger.getLogger(TaxonNameBase.class);
index 3009333075ffe80223e5228b7d1458091f4fb4b8..0d0209798b5b8f44756666240a3f9517f7ef6c43 100644 (file)
@@ -50,6 +50,7 @@ import eu.etaxonomy.cdm.common.DOI;
 import eu.etaxonomy.cdm.hibernate.search.DoiBridge;
 import eu.etaxonomy.cdm.model.agent.Institution;
 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
+import eu.etaxonomy.cdm.model.common.IIntextReferenceTarget;
 import eu.etaxonomy.cdm.model.common.TimePeriod;
 import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
@@ -122,7 +123,7 @@ public class Reference
         implements IArticle, IBook, IPatent, IDatabase, IJournal, IBookSection,ICdDvd,
                    IGeneric,IInProceedings, IProceedings, IPrintSeries, IReport,
                    IThesis,IWebPage, IPersonalCommunication,
-                   INomenclaturalReference, IReference,
+                   INomenclaturalReference, IReference, IIntextReferenceTarget,
                    Cloneable {
 
     private static final long serialVersionUID = -2034764545042691295L;
index ed232ef1a1e9fd78d80169bbfb17a3b1cb5b6274..355053bbf8bc4d7cb9dd2d1d46e8501ec9db8456 100644 (file)
@@ -40,6 +40,7 @@ import org.hibernate.search.annotations.Store;
 import eu.etaxonomy.cdm.common.CdmUtils;
 import eu.etaxonomy.cdm.hibernate.search.AcceptedTaxonBridge;
 import eu.etaxonomy.cdm.hibernate.search.ClassInfoBridge;
+import eu.etaxonomy.cdm.model.common.IIntextReferenceTarget;
 import eu.etaxonomy.cdm.model.common.IPublishable;
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
@@ -98,7 +99,7 @@ import eu.etaxonomy.cdm.validation.annotation.TaxonNameCannotBeAcceptedAndSynony
             impl = AcceptedTaxonBridge.class),
     @ClassBridge(impl = eu.etaxonomy.cdm.hibernate.search.NomenclaturalSortOrderBrigde.class)
 })
-public abstract class TaxonBase<S extends ITaxonCacheStrategy> extends IdentifiableEntity<S> implements  IPublishable, Cloneable {
+public abstract class TaxonBase<S extends ITaxonCacheStrategy> extends IdentifiableEntity<S> implements  IPublishable, IIntextReferenceTarget, Cloneable {
     private static final long serialVersionUID = -3589185949928938529L;
     private static final Logger logger = Logger.getLogger(TaxonBase.class);
 
index d5030d3564cb4e6826a9c122a3d44ebd47008617..6f4727dc097915644c5b4c1363629ec48c1a173c 100644 (file)
@@ -340,7 +340,7 @@ public class FullCoverageDataGenerator {
 
                Taxon referencedTaxon = getTaxon();
                cdmBases.add(referencedTaxon);
-               languageString.addIntextReference(IntextReference.NewTaxonInstance(referencedTaxon, languageString, 2, 5));
+               languageString.addIntextReference(IntextReference.NewInstance(referencedTaxon, languageString, 2, 5));
                textData.putModifyingText(eng, "nice diagnosis");
                handleAnnotatableEntity(textData);
                handleAnnotatableEntity(languageString);
index 6d6ff2295139067cf1be6ecd74b8150714524e1d..f665fe3a3a5b6c66a5263a07e9038f0d4bf52d0b 100644 (file)
@@ -40,8 +40,10 @@ import eu.etaxonomy.cdm.model.common.Annotation;
 import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.model.common.Extension;
 import eu.etaxonomy.cdm.model.common.ICdmBase;
+import eu.etaxonomy.cdm.model.common.IIntextReferencable;
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
 import eu.etaxonomy.cdm.model.common.Identifier;
+import eu.etaxonomy.cdm.model.common.IntextReference;
 import eu.etaxonomy.cdm.model.common.Marker;
 import eu.etaxonomy.cdm.model.name.BotanicalName;
 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
@@ -425,7 +427,7 @@ public class DeduplicationHelper {
                                identifiableEntity1.addIdentifier(clone);
                                removeListIdentifier.add(changeObject);
                        } catch (CloneNotSupportedException e) {
-                               e.printStackTrace();
+                           throw new RuntimeException(e);
                        }
                }
                for (Identifier<?> removeObject : removeListIdentifier){
@@ -549,13 +551,33 @@ public class DeduplicationHelper {
                        if (!cloneSet.contains(referencingObject)){
                        String className = refHolder.otherClass.getSimpleName();
                    String propertyName = refHolder.propertyName;
-                       String hql = "UPDATE " + className + " c SET c."+propertyName+" = :newValue WHERE c.id = :id";
+                       String hql = " UPDATE " + className + " c "
+                               + " SET c."+propertyName+" = :newValue "
+                               + " WHERE c.id = :id ";
                        Query query = session.createQuery(hql);
                        query.setEntity("newValue", cdmBase1);
                        query.setInteger("id",referencingObject.getId());
                        int rowCount = query.executeUpdate();
-                       logger.debug("Rows affected: " + rowCount);
+                       if (logger.isDebugEnabled()){logger.debug("Rows affected: " + rowCount);}
                        session.refresh(referencingObject);
+                       if (refHolder.otherClass == IntextReference.class){
+                           IntextReference intextRef = CdmBase.deproxy(referencingObject, IntextReference.class);
+                           IIntextReferencable refEnt = intextRef.getReferencedEntity();
+                           if (refEnt != null) {
+                        String newText = refEnt.getText() == null? null: refEnt.getText().replace(cdmBase2.getUuid().toString(), cdmBase1.getUuid().toString());
+                        refEnt.setText(newText);
+                        session.saveOrUpdate(refEnt);
+                    }
+
+                           //TODO
+                           /*
+                            * UPDATE LanguageString
+                            * SET text = Replace(text, cdmBase2.getUuuid(), cdmBase1.getUuid)
+                            * WHERE id IN (SELECT * FROM IntextReference
+                            *
+                            */
+                           System.out.println("IntextReference found");
+                       }
                }
            }
                session.flush();
index 7cb686eb85cee2a7e53a2061652b9402cb7db1e9..040866b7cc0c67fcff47b7c9094b697e582dc2e4 100644 (file)
@@ -120,7 +120,6 @@ import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
 import eu.etaxonomy.cdm.model.name.HybridRelationship;
 import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
 import eu.etaxonomy.cdm.model.name.IBotanicalName;
-import eu.etaxonomy.cdm.model.name.IZoologicalName;
 import eu.etaxonomy.cdm.model.name.NameRelationship;
 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
 import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
@@ -162,6 +161,7 @@ import eu.etaxonomy.cdm.persistence.dao.agent.IAgentDao;
 import eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao;
 import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
 import eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao;
+import eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao;
 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
 import eu.etaxonomy.cdm.strategy.match.DefaultMatchStrategy;
 import eu.etaxonomy.cdm.strategy.match.IMatchStrategy;
@@ -194,6 +194,9 @@ public class CdmGenericDaoImplTest extends CdmTransactionalIntegrationTest {
        @SpringBeanByType
        private IAgentDao agentDao;
 
+    @SpringBeanByType
+    private IReferenceDao referenceDao;
+
        /**
         * @throws java.lang.Exception
         */
@@ -821,7 +824,47 @@ public class CdmGenericDaoImplTest extends CdmTransactionalIntegrationTest {
 
     }
 
+    @Test
+    public void testReallocateIntextReference() throws MergeException {
+        UUID uuidRef1 = UUID.fromString("41743cec-b893-4e8b-b06c-91f9b9ba8fee");
+        UUID uuidRef2 = UUID.fromString("8fd56b43-7cca-4c3b-bb90-7576da81c072");
+
+        Reference ref1 = ReferenceFactory.newGeneric();
+        ref1.setTitle("Reference1");
+        ref1.setUuid(uuidRef1);
+        Reference ref2 = ReferenceFactory.newGeneric();
+        ref2.setTitle("Reference2");
+        ref2.setUuid(uuidRef2);
+        referenceDao.save(ref2);
+
+        TaxonNameBase<?,?> name1 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
+        name1.setTitleCache("BotanicalName1", true);
+        Taxon taxon = Taxon.NewInstance(name1, null);
+        TaxonDescription desc = TaxonDescription.NewInstance(taxon);
+        Language language = Language.DEFAULT();
+        TextData textData = TextData.NewInstance(Feature.DESCRIPTION(), "And here is a citation" , language, null);
+        LanguageString languageString = textData.getLanguageText(language);
+        IntextReference intextRef = languageString.addIntextReference(ref1, 4, 8);
+        String uuidIntextRef = intextRef.getUuid().toString();
+        desc.addElement(textData);
+        Assert.assertEquals("And <cdm:reference cdmId='"+ref1.getUuid()+"' intextId='"+uuidIntextRef+"'>here</cdm:reference> is a citation",
+                    languageString.getText());
+        taxonDao.save(taxon);
+
+        commitAndStartNewTransaction(null);
+        DefaultMergeStrategy strategy = DefaultMergeStrategy.NewInstance(Reference.class);
 
+        ref1 = referenceDao.findByUuid(ref1.getUuid());
+        ref2 = referenceDao.findByUuid(ref2.getUuid());
+        cdmGenericDao.merge(ref2, ref1, strategy);
+
+        taxon = (Taxon)taxonDao.findByUuid(taxon.getUuid());
+        textData = (TextData)taxon.getDescriptions().iterator().next().getElements().iterator().next();
+        languageString = textData.getLanguageText(language);
+        Assert.assertEquals("And <cdm:reference cdmId='"+ref2.getUuid()+"' intextId='"+uuidIntextRef+"'>here</cdm:reference> is a citation",
+                languageString.getText());
+
+    }
 
        /**
         * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.