- added significantIdentifer as search parameter to occurrenceService.findByTitle()
authorPatric Plitzner <p.plitzner@bgbm.org>
Tue, 12 May 2015 08:44:05 +0000 (08:44 +0000)
committerPatric Plitzner <p.plitzner@bgbm.org>
Tue, 12 May 2015 08:44:05 +0000 (08:44 +0000)
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/occurrence/OccurrenceDaoHibernateImpl.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/occurrence/IOccurrenceDao.java
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/OccurrenceServiceImpl.java
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/config/FindOccurrencesConfigurator.java
cdmlib-services/src/test/java/eu/etaxonomy/cdm/api/service/OccurrenceServiceTest.java
cdmlib-services/src/test/resources/eu/etaxonomy/cdm/api/service/OccurrenceServiceTest.testFindOcurrences.xml

index 7d5070cdb24aeaea53b7a88badfe42fcb07b3188..17e01678a271aa67ee8c0d34a32a88aea074a697 100644 (file)
@@ -330,11 +330,12 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
      */\r
     @Override\r
     public <T extends SpecimenOrObservationBase> List<T> findOccurrences(Class<T> clazz, String queryString,\r
-            SpecimenOrObservationType recordBasis, Taxon associatedTaxon, MatchMode matchmode, Integer limit,\r
+            String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon,\r
+            MatchMode matchmode, Integer limit,\r
             Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
 \r
-        Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, recordBasis, associatedTaxon, matchmode,\r
-                limit, start, orderHints, propertyPaths);\r
+        Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, significantIdentifier, recordBasis,\r
+                associatedTaxon, matchmode, limit, start, orderHints, propertyPaths);\r
 \r
         if(criteria!=null){\r
 \r
@@ -371,7 +372,7 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
      * @return\r
      */\r
     private <T extends SpecimenOrObservationBase> Criteria createFindOccurrenceCriteria(Class<T> clazz, String queryString,\r
-            SpecimenOrObservationType recordBasis, Taxon associatedTaxon, MatchMode matchmode, Integer limit,\r
+            String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon, MatchMode matchmode, Integer limit,\r
             Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
         Criteria criteria = null;\r
 \r
@@ -397,6 +398,12 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
             }\r
         }\r
 \r
+        //significant identifier\r
+        if (significantIdentifier != null) {\r
+            criteria.add(Restrictions.or(Restrictions.ilike("accessionNumber", significantIdentifier),\r
+                    Restrictions.ilike("catalogNumber", significantIdentifier), Restrictions.ilike("barcode", significantIdentifier)));\r
+        }\r
+\r
         //recordBasis/SpecimenOrObservationType\r
         if(recordBasis!=null){\r
             Set<SpecimenOrObservationType> typeAndSubtypes = recordBasis.getGeneralizationOf(true);\r
@@ -427,9 +434,10 @@ public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrOb
 \r
     @Override\r
     public <T extends SpecimenOrObservationBase> int countOccurrences(Class<T> clazz, String queryString,\r
-            SpecimenOrObservationType recordBasis, Taxon associatedTaxon, MatchMode matchmode, Integer limit,\r
-            Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
-        Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, recordBasis, associatedTaxon, matchmode, limit, start, orderHints, propertyPaths);\r
+            String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon,\r
+            MatchMode matchmode, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+        Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, significantIdentifier, recordBasis,\r
+                associatedTaxon, matchmode, limit, start, orderHints, propertyPaths);\r
 \r
         if(criteria!=null){\r
 \r
index 0e318ae568259abfbc6151aa76c7f626f2b62656..0942bff757ea5025c2add43d001650ef5036fb64 100644 (file)
@@ -66,26 +66,35 @@ public interface IOccurrenceDao extends IIdentifiableDao<SpecimenOrObservationBa
         */\r
        public List<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> type, TaxonBase determinedAs, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
 \r
-       /**\r
-        * Queries the database for specimens which match the given criteria\r
-        * @param clazz the class to match\r
-        * @param queryString the queryString to match\r
-        * @param type the {@link SpecimenOrObservationType} to match\r
-     * @param associatedTaxon the taxon these specimens are in any way associated to via\r
-     * determination, type designations, individuals associations, etc.\r
-        * @param matchmode determines how the query string should be matched\r
-        * @param limit\r
+           /**\r
+     * Queries the database for specimens which match the given criteria\r
+     *\r
+     * @param clazz\r
+     *            the class to match\r
+     * @param queryString\r
+     *            the queryString to match\r
+     * @param type\r
+     *            the {@link SpecimenOrObservationType} to match\r
+     * @param associatedTaxon\r
+     *            the taxon these specimens are in any way associated to via\r
+     *            determination, type designations, individuals associations,\r
+     *            etc.\r
+     * @param matchmode\r
+     *            determines how the query string should be matched\r
+     * @param limit\r
      *            the maximum number of entities returned (can be null to return\r
      *            all entities)\r
-        * @param start\r
-        * @param orderHints\r
-        *            Supports path like <code>orderHints.propertyNames</code> which\r
+     * @param start\r
+     * @param orderHints\r
+     *            Supports path like <code>orderHints.propertyNames</code> which\r
      *            include *-to-one properties like createdBy.username or\r
      *            authorTeam.persistentTitleCache\r
-        * @param propertyPaths\r
-        * @return a list of specimens that match the given parameters\r
-        */\r
-       public <T extends SpecimenOrObservationBase> List<T> findOccurrences(Class<T> clazz, String queryString, SpecimenOrObservationType type, Taxon determinedAs, MatchMode matchmode, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
+     * @param propertyPaths\r
+     * @return a list of specimens that match the given parameters\r
+     */\r
+    public <T extends SpecimenOrObservationBase> List<T> findOccurrences(Class<T> clazz, String queryString,\r
+            String significantIdentifier, SpecimenOrObservationType type, Taxon determinedAs, MatchMode matchmode,\r
+            Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
 \r
        /**\r
         * Returns the number of specimens that match the given parameters\r
@@ -105,9 +114,9 @@ public interface IOccurrenceDao extends IIdentifiableDao<SpecimenOrObservationBa
      *            authorTeam.persistentTitleCache\r
         * @return the number of found specimens\r
         */\r
-       public <T extends SpecimenOrObservationBase> int countOccurrences(Class<T> clazz, String queryString,\r
-            SpecimenOrObservationType recordBasis, Taxon associatedTaxon, MatchMode matchmode, Integer limit,\r
-            Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
+    public <T extends SpecimenOrObservationBase> int countOccurrences(Class<T> clazz, String queryString,\r
+            String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon,\r
+            MatchMode matchmode, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);\r
 \r
        /**\r
      * Returns a count of Media that are associated with a given occurence\r
index 9b5f16746b026bb65d1896e7e848184f44a96749..0537b9ab1aeff8e9eaf8a0423cffed67ef26c69e 100644 (file)
@@ -1335,8 +1335,10 @@ public class OccurrenceServiceImpl extends IdentifiableServiceBase<SpecimenOrObs
                     taxon = HibernateProxyHelper.deproxy(taxonBase, Taxon.class);\r
                 }\r
             }\r
-            occurrences.addAll(dao.findOccurrences(occurrenceConfig.getClazz(), occurrenceConfig.getTitleSearchString(), occurrenceConfig.getSpecimenType(),\r
-                    taxon, occurrenceConfig.getMatchMode(), null, null, occurrenceConfig.getOrderHints(), occurrenceConfig.getPropertyPaths()));\r
+            occurrences.addAll(dao.findOccurrences(occurrenceConfig.getClazz(),\r
+                    occurrenceConfig.getTitleSearchString(), occurrenceConfig.getSignificantIdentifier(),\r
+                    occurrenceConfig.getSpecimenType(), taxon, occurrenceConfig.getMatchMode(), null, null,\r
+                    occurrenceConfig.getOrderHints(), occurrenceConfig.getPropertyPaths()));\r
             return new DefaultPagerImpl<SpecimenOrObservationBase>(config.getPageNumber(), occurrences.size(), config.getPageSize(), occurrences);\r
         }\r
         return super.findByTitle(config);\r
@@ -1353,8 +1355,10 @@ public class OccurrenceServiceImpl extends IdentifiableServiceBase<SpecimenOrObs
                     taxon = HibernateProxyHelper.deproxy(taxonBase, Taxon.class);\r
                 }\r
             }\r
-            return dao.countOccurrences(occurrenceConfig.getClazz(), occurrenceConfig.getTitleSearchString(), occurrenceConfig.getSpecimenType(),\r
-                    taxon, occurrenceConfig.getMatchMode(), null, null, occurrenceConfig.getOrderHints(), occurrenceConfig.getPropertyPaths());\r
+            return dao.countOccurrences(occurrenceConfig.getClazz(), occurrenceConfig.getTitleSearchString(),\r
+                    occurrenceConfig.getSignificantIdentifier(), occurrenceConfig.getSpecimenType(), taxon,\r
+                    occurrenceConfig.getMatchMode(), null, null, occurrenceConfig.getOrderHints(),\r
+                    occurrenceConfig.getPropertyPaths());\r
         }\r
         return super.countByTitle(config);\r
     }\r
index 23ce63042bf007dd10ce95f2f07986fc680d4e1a..8671a9ad27cb14c7fc02e661e664e53d3c9a673d 100644 (file)
@@ -24,6 +24,13 @@ public class FindOccurrencesConfigurator extends IdentifiableServiceConfigurator
     private SpecimenOrObservationType specimenType;
     private UUID associatedTaxonUuid;
     private boolean isDetermined;
+    private String significantIdentifier;
+    public String getSignificantIdentifier() {
+        return significantIdentifier;
+    }
+    public void setSignificantIdentifier(String significantIdentifier) {
+        this.significantIdentifier = significantIdentifier;
+    }
     /**
      * @return the specimenType
      */
index 6efe6e745b842797eeb4c7ade346525de9f6160b..af8645d4e29ee206528450df2950fb94fef2da43 100644 (file)
@@ -803,10 +803,13 @@ public class OccurrenceServiceTest extends CdmTransactionalIntegrationTest {
 
 //        DerivedUnit derivedUnit = DerivedUnit.NewInstance(SpecimenOrObservationType.Fossil);
 //        derivedUnit.setTitleCache("testUnit1");
+//        derivedUnit.setAccessionNumber("ACC1");
 //        DerivedUnit derivedUnit2 = DerivedUnit.NewInstance(SpecimenOrObservationType.PreservedSpecimen);
 //        derivedUnit2.setTitleCache("testUnit2");
+//        derivedUnit2.setBarcode("ACC2");
 //        DerivedUnit dnaSample = DerivedUnit.NewInstance(SpecimenOrObservationType.DnaSample);
 //        dnaSample.setTitleCache("dna");
+//        dnaSample.setCatalogNumber("ACC1");
 //        DerivedUnit tissue = DerivedUnit.NewInstance(SpecimenOrObservationType.TissueSample);
 //        tissue.setTitleCache("tissue");
 //
@@ -904,6 +907,30 @@ public class OccurrenceServiceTest extends CdmTransactionalIntegrationTest {
         assertTrue(derivedUnits.contains(tissue));
         assertTrue(derivedUnits.contains(dnaSample));
 
+        //significant identifier search
+        config = new FindOccurrencesConfigurator();
+        config.setClazz(DerivedUnit.class);
+        config.setSignificantIdentifier("ACC1");
+        assertEquals(2, occurrenceService.countOccurrences(config));
+        List<SpecimenOrObservationBase> accessionedUnits = occurrenceService.findByTitle(config).getRecords();
+        assertEquals(2, accessionedUnits.size());
+        assertTrue(accessionedUnits.contains(derivedUnit1));
+        assertFalse(accessionedUnits.contains(derivedUnit2));
+        assertFalse(accessionedUnits.contains(tissue));
+        assertTrue(accessionedUnits.contains(dnaSample));
+
+        config = new FindOccurrencesConfigurator();
+        config.setClazz(DerivedUnit.class);
+        config.setSignificantIdentifier("ACC2");
+        assertEquals(1, occurrenceService.countOccurrences(config));
+        List<SpecimenOrObservationBase> barcodedUnits = occurrenceService.findByTitle(config).getRecords();
+        assertEquals(1, barcodedUnits.size());
+        assertFalse(barcodedUnits.contains(derivedUnit1));
+        assertTrue(barcodedUnits.contains(derivedUnit2));
+        assertFalse(barcodedUnits.contains(tissue));
+        assertFalse(barcodedUnits.contains(dnaSample));
+
+
         //recordBasis search => 1 Fossil
         config = new FindOccurrencesConfigurator();
         config.setSpecimenType(SpecimenOrObservationType.Fossil);
@@ -947,10 +974,13 @@ public class OccurrenceServiceTest extends CdmTransactionalIntegrationTest {
 
         DerivedUnit derivedUnit = DerivedUnit.NewInstance(SpecimenOrObservationType.Fossil);
         derivedUnit.setTitleCache("testUnit1");
+        derivedUnit.setAccessionNumber("ACC1");
         DerivedUnit derivedUnit2 = DerivedUnit.NewInstance(SpecimenOrObservationType.PreservedSpecimen);
         derivedUnit2.setTitleCache("testUnit2");
+        derivedUnit2.setBarcode("ACC2");
         DerivedUnit dnaSample = DerivedUnit.NewInstance(SpecimenOrObservationType.DnaSample);
         dnaSample.setTitleCache("dna");
+        dnaSample.setCatalogNumber("ACC1");
         DerivedUnit tissue = DerivedUnit.NewInstance(SpecimenOrObservationType.TissueSample);
         tissue.setTitleCache("tissue");
 
index 7e481ebd017c8c98e87f3d3f36a6d553f657c06b..d53f626f905e6ef91429e703174c101fa083d5f2 100644 (file)
@@ -1,13 +1,13 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <dataset>
-  <SPECIMENOROBSERVATIONBASE DTYPE="DerivedUnit" ID="5000" CREATED="2015-04-09 17:34:35.0" UUID="843bc8c9-c0fe-4735-bf40-82f1996dcefb" UPDATED="[null]" RECORDBASIS="FS" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="testUnit1" PUBLISH="true" INDIVIDUALCOUNT="[null]" ACCESSIONNUMBER="[null]" BARCODE="[null]" CATALOGNUMBER="[null]" COLLECTORSNUMBER="[null]" EXSICCATUM="[null]" ORIGINALLABELINFO="[null]" FIELDNOTES="[null]" FIELDNUMBER="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" LIFESTAGE_ID="[null]" SEX_ID="[null]" KINDOFUNIT_ID="[null]" COLLECTION_ID="[null]" DERIVEDFROM_ID="[null]" STOREDUNDER_ID="[null]" PRESERVATION_ID="[null]" GATHERINGEVENT_ID="[null]" PRIMARYCOLLECTOR_ID="[null]" MEDIASPECIMEN_ID="[null]" DNAQUALITY_ID="[null]"/>
-  <SPECIMENOROBSERVATIONBASE DTYPE="DerivedUnit" ID="5001" CREATED="2015-04-09 17:34:35.0" UUID="40cd9cb1-7c74-4e7d-a1f8-8a1e0314e940" UPDATED="[null]" RECORDBASIS="PS" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="testUnit2" PUBLISH="true" INDIVIDUALCOUNT="[null]" ACCESSIONNUMBER="[null]" BARCODE="[null]" CATALOGNUMBER="[null]" COLLECTORSNUMBER="[null]" EXSICCATUM="[null]" ORIGINALLABELINFO="[null]" FIELDNOTES="[null]" FIELDNUMBER="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" LIFESTAGE_ID="[null]" SEX_ID="[null]" KINDOFUNIT_ID="[null]" COLLECTION_ID="[null]" DERIVEDFROM_ID="[null]" STOREDUNDER_ID="[null]" PRESERVATION_ID="[null]" GATHERINGEVENT_ID="[null]" PRIMARYCOLLECTOR_ID="[null]" MEDIASPECIMEN_ID="[null]" DNAQUALITY_ID="[null]"/>
-  <SPECIMENOROBSERVATIONBASE DTYPE="DerivedUnit" ID="5002" CREATED="2015-04-09 17:34:35.0" UUID="364969a6-2457-4e2e-ae1e-29a6fcaa741a" UPDATED="[null]" RECORDBASIS="DS" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="dna" PUBLISH="true" INDIVIDUALCOUNT="[null]" ACCESSIONNUMBER="[null]" BARCODE="[null]" CATALOGNUMBER="[null]" COLLECTORSNUMBER="[null]" EXSICCATUM="[null]" ORIGINALLABELINFO="[null]" FIELDNOTES="[null]" FIELDNUMBER="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" LIFESTAGE_ID="[null]" SEX_ID="[null]" KINDOFUNIT_ID="[null]" COLLECTION_ID="[null]" DERIVEDFROM_ID="[null]" STOREDUNDER_ID="[null]" PRESERVATION_ID="[null]" GATHERINGEVENT_ID="[null]" PRIMARYCOLLECTOR_ID="[null]" MEDIASPECIMEN_ID="[null]" DNAQUALITY_ID="[null]"/>
-  <SPECIMENOROBSERVATIONBASE DTYPE="DerivedUnit" ID="5003" CREATED="2015-04-09 17:34:35.0" UUID="b608613c-1b5a-4882-8b14-d643b6fc5998" UPDATED="[null]" RECORDBASIS="TS" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="tissue" PUBLISH="true" INDIVIDUALCOUNT="[null]" ACCESSIONNUMBER="[null]" BARCODE="[null]" CATALOGNUMBER="[null]" COLLECTORSNUMBER="[null]" EXSICCATUM="[null]" ORIGINALLABELINFO="[null]" FIELDNOTES="[null]" FIELDNUMBER="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" LIFESTAGE_ID="[null]" SEX_ID="[null]" KINDOFUNIT_ID="[null]" COLLECTION_ID="[null]" DERIVEDFROM_ID="[null]" STOREDUNDER_ID="[null]" PRESERVATION_ID="[null]" GATHERINGEVENT_ID="[null]" PRIMARYCOLLECTOR_ID="[null]" MEDIASPECIMEN_ID="[null]" DNAQUALITY_ID="[null]"/>
-  <DESCRIPTIONELEMENTBASE DTYPE="IndividualsAssociation" ID="5000" CREATED="2015-04-09 17:34:35.0" UUID="f6c48856-0eef-4264-a484-afb340011247" UPDATED="2015-04-09 17:34:35.393" NAME="[null]" TIMEPERIOD_START="[null]" TIMEPERIOD_END="[null]" TIMEPERIOD_FREETEXT="[null]" ORDERRELEVANT="[null]" UNKNOWNDATA="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" FEATURE_ID="2052" INDESCRIPTION_ID="5000" AREA_ID="[null]" LANGUAGE_ID="[null]" STATUS_ID="[null]" ASSOCIATEDSPECIMENOROBSERVATION_ID="5000" UNIT_ID="[null]" TAXON2_ID="[null]" FORMAT_ID="[null]"/>
-  <DESCRIPTIONELEMENTBASE DTYPE="IndividualsAssociation" ID="5001" CREATED="2015-04-09 17:34:35.0" UUID="2e8895bf-e169-41d6-bb50-e7ea019d5fd0" UPDATED="2015-04-09 17:34:35.394" NAME="[null]" TIMEPERIOD_START="[null]" TIMEPERIOD_END="[null]" TIMEPERIOD_FREETEXT="[null]" ORDERRELEVANT="[null]" UNKNOWNDATA="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" FEATURE_ID="2052" INDESCRIPTION_ID="5000" AREA_ID="[null]" LANGUAGE_ID="[null]" STATUS_ID="[null]" ASSOCIATEDSPECIMENOROBSERVATION_ID="5003" UNIT_ID="[null]" TAXON2_ID="[null]" FORMAT_ID="[null]"/>
-  <DESCRIPTIONBASE DTYPE="TaxonDescription" ID="5000" CREATED="2015-04-09 17:34:35.0" UUID="272d4d28-662c-468e-94d8-16993fab91ba" UPDATED="2015-04-09 17:34:35.392" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Taxon description for Campanula patual" IMAGEGALLERY="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" SPECIMEN_ID="[null]" TAXON_ID="5000" TAXONNAME_ID="[null]"/>
-  <TAXONBASE DTYPE="Taxon" ID="5000" CREATED="2015-04-09 17:34:35.0" UUID="dfca7629-8a60-4d51-998d-371897f725e9" UPDATED="2015-04-09 17:34:35.388" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Campanula patual sec. ???" APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5000" SEC_ID="[null]" TAXONOMICPARENTCACHE_ID="[null]"/>
-  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5000" CREATED="2015-04-09 17:34:35.0" UUID="b3ffe006-cb94-4ab7-b157-b7d1345eac40" UPDATED="2015-04-09 17:34:35.39" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Campanula patual" APPENDEDPHRASE="[null]" FULLTITLECACHE="Campanula patual" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="Campanula" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="Campanula patual" PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="patual" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5000" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="765" BASIONYMAUTHORTEAM_ID="[null]" COMBINATIONAUTHORTEAM_ID="[null]" EXBASIONYMAUTHORTEAM_ID="[null]" EXCOMBINATIONAUTHORTEAM_ID="[null]"/>
-  <HOMOTYPICALGROUP ID="5000" CREATED="2015-04-09 17:34:35.0" UUID="203b89c9-d38f-4291-9e96-d99cb10035ec" UPDATED="2015-04-09 17:34:35.39" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
+  <SPECIMENOROBSERVATIONBASE DTYPE="DerivedUnit" ID="5000" CREATED="2015-05-12 04:59:12.0" UUID="843bc8c9-c0fe-4735-bf40-82f1996dcefb" UPDATED="[null]" RECORDBASIS="FS" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="testUnit1" PUBLISH="true" INDIVIDUALCOUNT="[null]" ACCESSIONNUMBER="ACC1" BARCODE="[null]" CATALOGNUMBER="[null]" COLLECTORSNUMBER="[null]" EXSICCATUM="[null]" ORIGINALLABELINFO="[null]" FIELDNOTES="[null]" FIELDNUMBER="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" LIFESTAGE_ID="[null]" SEX_ID="[null]" KINDOFUNIT_ID="[null]" COLLECTION_ID="[null]" DERIVEDFROM_ID="[null]" STOREDUNDER_ID="[null]" PRESERVATION_ID="[null]" GATHERINGEVENT_ID="[null]" PRIMARYCOLLECTOR_ID="[null]" MEDIASPECIMEN_ID="[null]" DNAQUALITY_ID="[null]"/>
+  <SPECIMENOROBSERVATIONBASE DTYPE="DerivedUnit" ID="5001" CREATED="2015-05-12 04:59:12.0" UUID="40cd9cb1-7c74-4e7d-a1f8-8a1e0314e940" UPDATED="[null]" RECORDBASIS="PS" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="testUnit2" PUBLISH="true" INDIVIDUALCOUNT="[null]" ACCESSIONNUMBER="[null]" BARCODE="ACC2" CATALOGNUMBER="[null]" COLLECTORSNUMBER="[null]" EXSICCATUM="[null]" ORIGINALLABELINFO="[null]" FIELDNOTES="[null]" FIELDNUMBER="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" LIFESTAGE_ID="[null]" SEX_ID="[null]" KINDOFUNIT_ID="[null]" COLLECTION_ID="[null]" DERIVEDFROM_ID="[null]" STOREDUNDER_ID="[null]" PRESERVATION_ID="[null]" GATHERINGEVENT_ID="[null]" PRIMARYCOLLECTOR_ID="[null]" MEDIASPECIMEN_ID="[null]" DNAQUALITY_ID="[null]"/>
+  <SPECIMENOROBSERVATIONBASE DTYPE="DerivedUnit" ID="5002" CREATED="2015-05-12 04:59:12.0" UUID="364969a6-2457-4e2e-ae1e-29a6fcaa741a" UPDATED="[null]" RECORDBASIS="DS" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="dna" PUBLISH="true" INDIVIDUALCOUNT="[null]" ACCESSIONNUMBER="[null]" BARCODE="[null]" CATALOGNUMBER="ACC1" COLLECTORSNUMBER="[null]" EXSICCATUM="[null]" ORIGINALLABELINFO="[null]" FIELDNOTES="[null]" FIELDNUMBER="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" LIFESTAGE_ID="[null]" SEX_ID="[null]" KINDOFUNIT_ID="[null]" COLLECTION_ID="[null]" DERIVEDFROM_ID="[null]" STOREDUNDER_ID="[null]" PRESERVATION_ID="[null]" GATHERINGEVENT_ID="[null]" PRIMARYCOLLECTOR_ID="[null]" MEDIASPECIMEN_ID="[null]" DNAQUALITY_ID="[null]"/>
+  <SPECIMENOROBSERVATIONBASE DTYPE="DerivedUnit" ID="5003" CREATED="2015-05-12 04:59:12.0" UUID="b608613c-1b5a-4882-8b14-d643b6fc5998" UPDATED="[null]" RECORDBASIS="TS" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="tissue" PUBLISH="true" INDIVIDUALCOUNT="[null]" ACCESSIONNUMBER="[null]" BARCODE="[null]" CATALOGNUMBER="[null]" COLLECTORSNUMBER="[null]" EXSICCATUM="[null]" ORIGINALLABELINFO="[null]" FIELDNOTES="[null]" FIELDNUMBER="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" LIFESTAGE_ID="[null]" SEX_ID="[null]" KINDOFUNIT_ID="[null]" COLLECTION_ID="[null]" DERIVEDFROM_ID="[null]" STOREDUNDER_ID="[null]" PRESERVATION_ID="[null]" GATHERINGEVENT_ID="[null]" PRIMARYCOLLECTOR_ID="[null]" MEDIASPECIMEN_ID="[null]" DNAQUALITY_ID="[null]"/>
+  <DESCRIPTIONELEMENTBASE DTYPE="IndividualsAssociation" ID="5000" CREATED="2015-05-12 04:59:12.0" UUID="75a36571-fc84-4374-a6e2-4fec8b688bce" UPDATED="2015-05-12 04:59:12.537" NAME="[null]" TIMEPERIOD_START="[null]" TIMEPERIOD_END="[null]" TIMEPERIOD_FREETEXT="[null]" ORDERRELEVANT="[null]" UNKNOWNDATA="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" FEATURE_ID="2052" INDESCRIPTION_ID="5000" AREA_ID="[null]" LANGUAGE_ID="[null]" STATUS_ID="[null]" ASSOCIATEDSPECIMENOROBSERVATION_ID="5003" UNIT_ID="[null]" TAXON2_ID="[null]" FORMAT_ID="[null]"/>
+  <DESCRIPTIONELEMENTBASE DTYPE="IndividualsAssociation" ID="5001" CREATED="2015-05-12 04:59:12.0" UUID="b42ddb10-4deb-427b-ad8a-0e1c6370f8c6" UPDATED="2015-05-12 04:59:12.538" NAME="[null]" TIMEPERIOD_START="[null]" TIMEPERIOD_END="[null]" TIMEPERIOD_FREETEXT="[null]" ORDERRELEVANT="[null]" UNKNOWNDATA="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" FEATURE_ID="2052" INDESCRIPTION_ID="5000" AREA_ID="[null]" LANGUAGE_ID="[null]" STATUS_ID="[null]" ASSOCIATEDSPECIMENOROBSERVATION_ID="5000" UNIT_ID="[null]" TAXON2_ID="[null]" FORMAT_ID="[null]"/>
+  <DESCRIPTIONBASE DTYPE="TaxonDescription" ID="5000" CREATED="2015-05-12 04:59:12.0" UUID="272d4d28-662c-468e-94d8-16993fab91ba" UPDATED="2015-05-12 04:59:12.536" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Taxon description for Campanula patual" IMAGEGALLERY="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" SPECIMEN_ID="[null]" TAXON_ID="5000" TAXONNAME_ID="[null]"/>
+  <TAXONBASE DTYPE="Taxon" ID="5000" CREATED="2015-05-12 04:59:12.0" UUID="dfca7629-8a60-4d51-998d-371897f725e9" UPDATED="2015-05-12 04:59:12.531" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Campanula patual sec. ???" APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5000" SEC_ID="[null]" TAXONOMICPARENTCACHE_ID="[null]"/>
+  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5000" CREATED="2015-05-12 04:59:12.0" UUID="d8216f34-f98e-4f54-9c5c-d39aabd4f90e" UPDATED="2015-05-12 04:59:12.533" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Campanula patual" APPENDEDPHRASE="[null]" FULLTITLECACHE="Campanula patual" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="Campanula" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="Campanula patual" PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="patual" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5000" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="765" BASIONYMAUTHORTEAM_ID="[null]" COMBINATIONAUTHORTEAM_ID="[null]" EXBASIONYMAUTHORTEAM_ID="[null]" EXCOMBINATIONAUTHORTEAM_ID="[null]"/>
+  <HOMOTYPICALGROUP ID="5000" CREATED="2015-05-12 04:59:12.0" UUID="07104985-6479-4231-b610-bba7c689645d" UPDATED="2015-05-12 04:59:12.534" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
 </dataset>