AT SPecimen imports updated (now with Identifications)
authorAndreas Müller <a.mueller@bgbm.org>
Fri, 14 Dec 2012 02:01:35 +0000 (02:01 +0000)
committerAndreas Müller <a.mueller@bgbm.org>
Fri, 14 Dec 2012 02:01:35 +0000 (02:01 +0000)
.gitattributes
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraEcoFactImport.java [new file with mode: 0644]
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraFactEcologyImport.java [new file with mode: 0644]
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraImportConfigurator.java
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraImportState.java
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraSpecimenImportBase.java
app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraTypeImport.java

index 31762b00394b9b3454f06518078e3ebdcb0c27d1..e13e4ba729a8614fdf16f555c43e72cd377a30ce 100644 (file)
@@ -102,6 +102,8 @@ app-import/src/main/java/eu/etaxonomy/cdm/io/PalmaeImageImport.java -text
 app-import/src/main/java/eu/etaxonomy/cdm/io/PalmaeProtologueImport.java -text
 app-import/src/main/java/eu/etaxonomy/cdm/io/ProtologueImport.java -text
 app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraCollectionImport.java -text
+app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraEcoFactImport.java -text
+app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraFactEcologyImport.java -text
 app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraImageImportBase.java -text
 app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraImportConfigurator.java -text
 app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraImportState.java -text
diff --git a/app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraEcoFactImport.java b/app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraEcoFactImport.java
new file mode 100644 (file)
index 0000000..4b5e963
--- /dev/null
@@ -0,0 +1,516 @@
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\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.io.algaterra;\r
+\r
+import java.sql.ResultSet;\r
+import java.sql.SQLException;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.UUID;\r
+\r
+import org.apache.commons.lang.StringUtils;\r
+import org.apache.log4j.Logger;\r
+import org.springframework.stereotype.Component;\r
+\r
+import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;\r
+import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade.DerivedUnitType;\r
+import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeNotSupportedException;\r
+import eu.etaxonomy.cdm.io.algaterra.validation.AlgaTerraSpecimenImportValidator;\r
+import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator;\r
+import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;\r
+import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTaxonImport;\r
+import eu.etaxonomy.cdm.io.common.IOValidator;\r
+import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+import eu.etaxonomy.cdm.model.common.DefinedTermBase;\r
+import eu.etaxonomy.cdm.model.common.Language;\r
+import eu.etaxonomy.cdm.model.common.Marker;\r
+import eu.etaxonomy.cdm.model.common.MarkerType;\r
+import eu.etaxonomy.cdm.model.common.TermVocabulary;\r
+import eu.etaxonomy.cdm.model.description.CategoricalData;\r
+import eu.etaxonomy.cdm.model.description.DescriptionBase;\r
+import eu.etaxonomy.cdm.model.description.Feature;\r
+import eu.etaxonomy.cdm.model.description.IndividualsAssociation;\r
+import eu.etaxonomy.cdm.model.description.MeasurementUnit;\r
+import eu.etaxonomy.cdm.model.description.Modifier;\r
+import eu.etaxonomy.cdm.model.description.QuantitativeData;\r
+import eu.etaxonomy.cdm.model.description.State;\r
+import eu.etaxonomy.cdm.model.description.StatisticalMeasure;\r
+import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;\r
+import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
+import eu.etaxonomy.cdm.model.description.TextData;\r
+import eu.etaxonomy.cdm.model.name.BotanicalName;\r
+import eu.etaxonomy.cdm.model.name.Rank;\r
+import eu.etaxonomy.cdm.model.occurrence.Collection;\r
+import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;\r
+import eu.etaxonomy.cdm.model.occurrence.DerivedUnitBase;\r
+import eu.etaxonomy.cdm.model.occurrence.FieldObservation;\r
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;\r
+import eu.etaxonomy.cdm.model.reference.Reference;\r
+import eu.etaxonomy.cdm.model.taxon.Taxon;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
+\r
+\r
+/**\r
+ * @author a.mueller\r
+ * @created 01.09.2012\r
+ */\r
+@Component\r
+public class AlgaTerraEcoFactImport  extends AlgaTerraSpecimenImportBase {\r
+       private static final Logger logger = Logger.getLogger(AlgaTerraEcoFactImport.class);\r
+\r
+       \r
+       private static int modCount = 5000;\r
+       private static final String pluralString = "eco facts";\r
+       private static final String dbTableName = "EcoFact";  //??  \r
+\r
+\r
+       public AlgaTerraEcoFactImport(){\r
+               super(dbTableName, pluralString);\r
+       }\r
+       \r
+       \r
+       \r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getIdQuery()\r
+        */\r
+       @Override\r
+       protected String getIdQuery(BerlinModelImportState state) {\r
+               String result = " SELECT EcoFactId " + \r
+                               " FROM EcoFact  " +\r
+                               " ORDER BY EcoFact.DuplicateFk, EcoFact.EcoFactId ";\r
+               return result;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)\r
+        */\r
+       @Override\r
+       protected String getRecordQuery(BerlinModelImportConfigurator config) {\r
+                       String strQuery =   \r
+            " SELECT EcoFact.*, EcoFact.EcoFactId as unitId, " + \r
+               " tg.ID AS GazetteerId, tg.L2Code, tg.L3Code, tg.L4Code, tg.Country, tg.ISOCountry, " +\r
+               " ec.UUID as climateUuid, eh.UUID as habitatUuid, elf.UUID as lifeFormUuid " +\r
+            " FROM EcoFact " +\r
+                 " LEFT OUTER JOIN TDWGGazetteer tg ON EcoFact.TDWGGazetteerFk = tg.ID " +\r
+                 " LEFT OUTER JOIN EcoClimate  ec  ON EcoFact.ClimateFk  = ec.ClimateId " +\r
+                 " LEFT OUTER JOIN EcoHabitat  eh  ON EcoFact.HabitatFk  = eh.HabitatId " +\r
+                 " LEFT OUTER JOIN EcoLifeForm elf ON EcoFact.LifeFormFk = elf.LifeFormId " +\r
+              " WHERE (EcoFact.EcoFactId IN (" + ID_LIST_TOKEN + ")  )"  \r
+            + " ORDER BY EcoFact.DuplicateFk, EcoFact.EcoFactId "\r
+            ;\r
+               return strQuery;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)\r
+        */\r
+       public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState bmState) {\r
+               boolean success = true;\r
+               \r
+               AlgaTerraImportState state = (AlgaTerraImportState)bmState;\r
+               try {\r
+                       makeVocabulariesAndFeatures(state);\r
+               } catch (SQLException e1) {\r
+                       logger.warn("Exception occurred when trying to create Ecofact vocabularies: " + e1.getMessage());\r
+                       e1.printStackTrace();\r
+               }\r
+               Set<SpecimenOrObservationBase> objectsToSave = new HashSet<SpecimenOrObservationBase>();\r
+               \r
+               //TODO do we still need this map? EcoFacts are not handled separate from Facts.\r
+               //However, they have duplicates on derived unit level. Also check duplicateFk. \r
+               Map<String, FieldObservation> ecoFactFieldObservationMap = (Map<String, FieldObservation>) partitioner.getObjectMap(ECO_FACT_FIELD_OBSERVATION_NAMESPACE);\r
+               \r
+               ResultSet rs = partitioner.getResultSet();\r
+\r
+               try {\r
+                       \r
+                       int i = 0;\r
+\r
+                       //for each reference\r
+            while (rs.next()){\r
+                \r
+                       if ((i++ % modCount) == 0 && i!= 1 ){ logger.info(pluralString + " handled: " + (i-1));}\r
+                               \r
+                               int ecoFactId = rs.getInt("EcoFactId");\r
+                               Integer duplicateFk = nullSafeInt(rs, "DuplicateFk");\r
+                               \r
+                               //FIXME RecordBasis is in Fact table, which is not part of the query anymore.\r
+                               //Some EcoFacts have multiple RecordBasis types in Fact. Henning will check this.\r
+//                             String recordBasis = rs.getString("RecordBasis");\r
+                               String recordBasis = "PreservedSpecimen";\r
+                               \r
+                               try {\r
+                                       \r
+                                       //source ref\r
+                                       Reference<?> sourceRef = state.getTransactionalSourceReference();\r
+                               \r
+                                       //facade\r
+                                       DerivedUnitType type = makeDerivedUnitType(recordBasis);\r
+                                       \r
+                                       DerivedUnitFacade facade;\r
+                                       //field observation\r
+                                       if (duplicateFk == null){\r
+                                               facade = DerivedUnitFacade.NewInstance(type);\r
+                                               handleFieldObservationSpecimen(rs, facade, state, partitioner);\r
+                                               handleEcoFactSpecificFieldObservation(rs,facade, state);\r
+                                               FieldObservation fieldObservation = facade.getFieldObservation(true);\r
+                                               ecoFactFieldObservationMap.put(String.valueOf(ecoFactId), fieldObservation);\r
+                                       }else{\r
+                                               FieldObservation fieldObservation = ecoFactFieldObservationMap.get(String.valueOf(duplicateFk));\r
+                                               facade = DerivedUnitFacade.NewInstance(type, fieldObservation);\r
+                                       }\r
+                                               \r
+                                       handleFirstDerivedSpecimen(rs, facade, state, partitioner);\r
+                                       handleEcoFactSpecificDerivedUnit(rs,facade, state);\r
+\r
+                                       \r
+                                       DerivedUnitBase<?> objectToSave = facade.innerDerivedUnit();\r
+                                       objectsToSave.add(objectToSave); \r
+                                       \r
+\r
+                               } catch (Exception e) {\r
+                                       logger.warn("Exception in ecoFact: ecoFactId " + ecoFactId + ". " + e.getMessage());\r
+                                       e.printStackTrace();\r
+                               } \r
+                \r
+            }\r
+           \r
+//            logger.warn("Specimen: " + countSpecimen + ", Descriptions: " + countDescriptions );\r
+\r
+                       logger.warn("Taxa to save: " + objectsToSave.size());\r
+                       getOccurrenceService().save(objectsToSave);     \r
+                       \r
+                       return success;\r
+               } catch (SQLException e) {\r
+                       logger.error("SQLException:" +  e);\r
+                       return false;\r
+               }\r
+       }\r
+       \r
+       protected String getDerivedUnitNameSpace(){\r
+               return ECO_FACT_DERIVED_UNIT_NAMESPACE;\r
+       }\r
+       \r
+       protected String getFieldObservationNameSpace(){\r
+               return ECO_FACT_FIELD_OBSERVATION_NAMESPACE;\r
+       }\r
+\r
+\r
+\r
+       private void handleEcoFactSpecificFieldObservation(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state) throws SQLException {\r
+               \r
+               Object alkalinityFlag = rs.getBoolean("AlkalinityFlag");\r
+               \r
+               //alkalinity marker\r
+               if (alkalinityFlag != null){\r
+                       MarkerType alkalinityMarkerType = getMarkerType(state, uuidMarkerAlkalinity, "Alkalinity", "Alkalinity", null);\r
+                       boolean alkFlag = Boolean.valueOf(alkalinityFlag.toString());\r
+                       Marker alkalinityMarker = Marker.NewInstance(alkalinityMarkerType, alkFlag);\r
+                       facade.getFieldObservation(true).addMarker(alkalinityMarker);\r
+               }\r
+               \r
+               \r
+               DescriptionBase<?> fieldDescription = getFieldObservationDescription(facade);\r
+\r
+               //habitat, ecology, community, etc.\r
+               String habitat = rs.getString("HabitatExplanation");\r
+               \r
+               if (isNotBlank(habitat)){\r
+                       Feature habitatExplanation = getFeature(state, uuidFeatureHabitatExplanation, "Habitat Explanation", "HabitatExplanation", null, null);\r
+                       TextData textData = TextData.NewInstance(habitatExplanation);\r
+                       textData.putText(Language.DEFAULT(), habitat);\r
+                       fieldDescription.addElement(textData);\r
+               }\r
+               \r
+               String community = rs.getString("Comunity");\r
+               if (isNotBlank(community)){\r
+                       Feature communityFeature = getFeature(state, uuidFeatureSpecimenCommunity, "Community", "The community of a specimen (e.g. other algae in the same sample)", null, null);\r
+                       TextData textData = TextData.NewInstance(communityFeature);\r
+                       textData.putText(Language.DEFAULT(), community);\r
+                       fieldDescription.addElement(textData);\r
+               }\r
+\r
+               String additionalData = rs.getString("AdditionalData");\r
+               if (isNotBlank(additionalData)){  //or handle it as Annotation ??\r
+                       Feature additionalDataFeature = getFeature(state, uuidFeatureAdditionalData, "Additional Data", "Additional Data", null, null);\r
+                       TextData textData = TextData.NewInstance(additionalDataFeature);\r
+                       textData.putText(Language.DEFAULT(), additionalData);\r
+                       fieldDescription.addElement(textData);\r
+               }\r
+               \r
+               String climateUuid = rs.getString("climateUuid");\r
+               String habitatUuid = rs.getString("habitatUuid");\r
+               String lifeFormUuid = rs.getString("lifeFormUuid");\r
+               \r
+               addCategoricalValue(state, fieldDescription, climateUuid, uuidFeatureAlgaTerraClimate);\r
+               addCategoricalValue(state, fieldDescription, habitatUuid, Feature.HABITAT().getUuid());\r
+               addCategoricalValue(state, fieldDescription, lifeFormUuid, uuidFeatureAlgaTerraLifeForm);\r
+               \r
+\r
+               \r
+               //parameters\r
+               makeParameter(state, rs, getFieldObservationDescription(facade));\r
+\r
+       }\r
+       \r
+       private void handleEcoFactSpecificDerivedUnit(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state) throws SQLException {\r
+               //collection\r
+               String voucher = rs.getString("Voucher");\r
+               if (StringUtils.isNotBlank(voucher)){\r
+                       facade.setAccessionNumber(voucher);\r
+               }\r
+       }\r
+\r
+\r
+\r
+\r
+\r
+       private void addCategoricalValue(AlgaTerraImportState importState, DescriptionBase description, String uuidTerm, UUID featureUuid) {\r
+               if (uuidTerm != null){\r
+                       State state = this.getStateTerm(importState, UUID.fromString(uuidTerm));\r
+                       Feature feature = getFeature(importState, featureUuid);\r
+                       CategoricalData categoricalData = CategoricalData.NewInstance(state, feature);\r
+                       description.addElement(categoricalData);\r
+               }\r
+       }\r
+\r
+       private void makeParameter(AlgaTerraImportState state, ResultSet rs, DescriptionBase<?> descriptionBase) throws SQLException {\r
+               for (int i = 1; i <= 10; i++){\r
+                       String valueStr = rs.getString(String.format("P%dValue", i));\r
+                       String unitStr = rs.getString(String.format("P%dUnit", i));\r
+                       String parameter = rs.getString(String.format("P%dParameter", i));\r
+                       String method = rs.getString(String.format("P%dMethod", i));\r
+                       \r
+                       //method\r
+                       if (StringUtils.isNotBlank(method)){\r
+                               logger.warn("Methods not yet handled: " + method);\r
+                       }\r
+                       //parameter\r
+                       TermVocabulary<Feature> vocParameter = getVocabulary(uuidVocParameter, "Feature vocabulary for AlgaTerra measurement parameters", "Parameters", null, null, false, Feature.COMMON_NAME());\r
+                       if (StringUtils.isNotBlank(parameter)){\r
+                               UUID featureUuid = getParameterFeatureUuid(state, parameter);\r
+                               Feature feature = getFeature(state, featureUuid, parameter, parameter, null, vocParameter);\r
+                               QuantitativeData quantData = QuantitativeData.NewInstance(feature);\r
+                               \r
+                               //unit\r
+                               MeasurementUnit unit = getMeasurementUnit(state, unitStr);\r
+                               quantData.setUnit(unit);\r
+                               try {\r
+                                       \r
+                                       Set<Modifier> valueModifier = new HashSet<Modifier>();\r
+                                       valueStr = normalizeAndModifyValue(state, valueStr, valueModifier);\r
+                                       //value\r
+                                       Float valueFlt = Float.valueOf(valueStr);  //TODO maybe change model to Double ??\r
+                                       \r
+                                       StatisticalMeasure measureSingleValue = getStatisticalMeasure(state, uuidStatMeasureSingleValue, "Value", "Single measurement value", null, null);\r
+                                       StatisticalMeasurementValue value = StatisticalMeasurementValue.NewInstance(measureSingleValue, valueFlt); \r
+                                       quantData.addStatisticalValue(value);\r
+                                       descriptionBase.addElement(quantData);\r
+                                       \r
+                               } catch (NumberFormatException e) {\r
+                                       logger.warn(String.format("Value '%s' can't be converted to double. Parameter %s not imported.", valueStr, parameter));\r
+                               }\r
+                       }else if (isNotBlank(valueStr) || isNotBlank(unitStr) ){\r
+                               logger.warn("There is value or unit without parameter: " + i);\r
+                       }\r
+                       \r
+                       \r
+               }\r
+               \r
+       }\r
+\r
+       private String normalizeAndModifyValue(AlgaTerraImportState state, String valueStr, Set<Modifier> valueModifier) {\r
+               valueStr = valueStr.replace(",", ".");\r
+               if (valueStr.startsWith("<")){\r
+                       TermVocabulary<Modifier> measurementValueModifierVocabulary = getVocabulary(uuidMeasurementValueModifier, "Measurement value modifier", "Measurement value modifier", null, null, false, Modifier.NewInstance());\r
+                       Modifier modifier = getModifier(state, uuidModifierLowerThan, "Lower", "Lower than the given measurement value", "<", measurementValueModifierVocabulary);\r
+                       valueModifier.add(modifier);\r
+                       valueStr = valueStr.replace("<", "");\r
+               }\r
+               if (valueStr.startsWith(">")){\r
+                       TermVocabulary<Modifier> measurementValueModifierVocabulary = getVocabulary(uuidMeasurementValueModifier, "Measurement value modifier", "Measurement value modifier", null, null, false, Modifier.NewInstance());\r
+                       Modifier modifier = getModifier(state, uuidModifierGreaterThan, "Lower", "Lower than the given measurement value", "<", measurementValueModifierVocabulary);\r
+                       valueModifier.add(modifier);\r
+                       valueStr = valueStr.replace(">", "");\r
+               }\r
+               return valueStr;\r
+       }\r
+\r
+\r
+\r
+       private UUID getParameterFeatureUuid(AlgaTerraImportState state, String key) {\r
+               //TODO define some UUIDs in Transformer\r
+               UUID uuid = state.getParameterFeatureUuid(key);\r
+               if (uuid == null){\r
+                       uuid = UUID.randomUUID();\r
+                       state.putParameterFeatureUuid(key, uuid);\r
+               }\r
+               return uuid;\r
+       }\r
+\r
+\r
+\r
+       /**\r
+        * TODO move to InputTransformerBase\r
+        * @param state\r
+        * @param unitStr\r
+        * @return\r
+        */\r
+       private MeasurementUnit getMeasurementUnit(AlgaTerraImportState state, String unitStr) {\r
+               if (StringUtils.isNotBlank(unitStr)){\r
+                       UUID uuidMeasurementUnitMgL = UUID.fromString("7ac302c5-3cbd-4334-964a-bf5d11eb9ead");\r
+                       UUID uuidMeasurementUnitMolMol = UUID.fromString("96b78d78-3e49-448f-8100-e7779b71dd53");\r
+                       UUID uuidMeasurementUnitMicroMolSiL = UUID.fromString("2cb8bc85-a4af-42f1-b80b-34c36c9f75d4");\r
+                       UUID uuidMeasurementUnitMicroMolL = UUID.fromString("a631f62e-377e-405c-bd1a-76885b13a72b");\r
+                       UUID uuidMeasurementUnitDegreeC = UUID.fromString("55222aec-d5be-413e-8db7-d9a48c316c6c");\r
+                       UUID uuidMeasurementUnitPercent = UUID.fromString("3ea3110e-f048-4bed-8bfe-33c60f63626f");\r
+                       UUID uuidMeasurementUnitCm = UUID.fromString("3ea3110e-f048-4bed-8bfe-33c60f63626f");\r
+                       UUID uuidMeasurementUnitMicroSiCm = UUID.fromString("3ea3110e-f048-4bed-8bfe-33c60f63626f");\r
+                       \r
+                       \r
+                       if (unitStr.equalsIgnoreCase("mg/L")){\r
+                               return getMeasurementUnit(state, uuidMeasurementUnitMgL, unitStr, unitStr, unitStr, null);\r
+                       }else if (unitStr.equalsIgnoreCase("mol/mol")){\r
+                               return getMeasurementUnit(state, uuidMeasurementUnitMolMol, unitStr, unitStr, unitStr, null);\r
+                       }else if (unitStr.equalsIgnoreCase("\u00B5mol Si/L")){   //µmol Si/L\r
+                               return getMeasurementUnit(state, uuidMeasurementUnitMicroMolSiL, unitStr, unitStr, unitStr, null);\r
+                       }else if (unitStr.equalsIgnoreCase("\u00B5mol/L")){             //µmol/L\r
+                               return getMeasurementUnit(state, uuidMeasurementUnitMicroMolL, unitStr, unitStr, unitStr, null);\r
+                       }else if (unitStr.equalsIgnoreCase("\u00B0C")){               //°C\r
+                               return getMeasurementUnit(state, uuidMeasurementUnitDegreeC, unitStr, unitStr, unitStr, null);\r
+                       }else if (unitStr.equalsIgnoreCase("%")){\r
+                               return getMeasurementUnit(state, uuidMeasurementUnitPercent, unitStr, unitStr, unitStr, null);\r
+                       }else if (unitStr.equalsIgnoreCase("cm")){\r
+                               return getMeasurementUnit(state, uuidMeasurementUnitCm, unitStr, unitStr, unitStr, null);\r
+                       }else if (unitStr.equalsIgnoreCase("\u00B5S/cm")){   //µS/cm\r
+                               return getMeasurementUnit(state, uuidMeasurementUnitMicroSiCm, unitStr, unitStr, unitStr, null);\r
+                       }else{\r
+                               logger.warn("MeasurementUnit was not recognized");\r
+                               return null;\r
+                       }\r
+               }else{\r
+                       return null;\r
+               }\r
+       }\r
+\r
+       private Feature makeFeature(DerivedUnitType type) {\r
+               if (type.equals(DerivedUnitType.DerivedUnit)){\r
+                       return Feature.INDIVIDUALS_ASSOCIATION();\r
+               }else if (type.equals(DerivedUnitType.FieldObservation) || type.equals(DerivedUnitType.Observation) ){\r
+                       return Feature.OBSERVATION();\r
+               }else if (type.equals(DerivedUnitType.Fossil) || type.equals(DerivedUnitType.LivingBeing) || type.equals(DerivedUnitType.Specimen )){\r
+                       return Feature.SPECIMEN();\r
+               }\r
+               logger.warn("No feature defined for derived unit type: " + type);\r
+               return null;\r
+       }\r
+\r
+\r
+       private DerivedUnitType makeDerivedUnitType(String recordBasis) {\r
+               DerivedUnitType result = null;\r
+               if (StringUtils.isBlank(recordBasis)){\r
+                       result = DerivedUnitType.DerivedUnit;\r
+               } else if (recordBasis.equalsIgnoreCase("FossileSpecimen")){\r
+                       result = DerivedUnitType.Fossil;\r
+               }else if (recordBasis.equalsIgnoreCase("HumanObservation")){\r
+                       result = DerivedUnitType.Observation;\r
+               }else if (recordBasis.equalsIgnoreCase("Literature")){\r
+                       logger.warn("Literature record basis not yet supported");\r
+                       result = DerivedUnitType.DerivedUnit;\r
+               }else if (recordBasis.equalsIgnoreCase("LivingSpecimen")){\r
+                       result = DerivedUnitType.LivingBeing;\r
+               }else if (recordBasis.equalsIgnoreCase("MachineObservation")){\r
+                       logger.warn("MachineObservation record basis not yet supported");\r
+                       result = DerivedUnitType.Observation;\r
+               }else if (recordBasis.equalsIgnoreCase("PreservedSpecimen")){\r
+                       result = DerivedUnitType.Specimen;\r
+               }\r
+               return result;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)\r
+        */\r
+       public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs) {\r
+               String nameSpace;\r
+               Class cdmClass;\r
+               Set<String> idSet;\r
+               Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();\r
+               \r
+               try{\r
+                       Set<String> fieldObservationIdSet = new HashSet<String>();\r
+                       Set<String> termsIdSet = new HashSet<String>();\r
+                       Set<String> collectionIdSet = new HashSet<String>();\r
+                       \r
+                       while (rs.next()){\r
+                               handleForeignKey(rs, fieldObservationIdSet, "DuplicateFk");\r
+                               handleForeignKey(rs, termsIdSet, "ClimateFk");\r
+                               handleForeignKey(rs, termsIdSet, "HabitatFk");\r
+                               handleForeignKey(rs, termsIdSet, "LifeFormFk");\r
+                               handleForeignKey(rs, collectionIdSet, "CollectionFk");\r
+                       }\r
+                       \r
+                       //field observation map for duplicates\r
+                       nameSpace = AlgaTerraEcoFactImport.ECO_FACT_FIELD_OBSERVATION_NAMESPACE;\r
+                       cdmClass = FieldObservation.class;\r
+                       idSet = fieldObservationIdSet;\r
+                       Map<String, FieldObservation> fieldObservationMap = (Map<String, FieldObservation>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, fieldObservationMap);\r
+\r
+                       //collections\r
+                       nameSpace = AlgaTerraCollectionImport.NAMESPACE_COLLECTION;\r
+                       cdmClass = Collection.class;\r
+                       idSet = collectionIdSet;\r
+                       Map<String, Collection> collectionMap = (Map<String, Collection>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, collectionMap);\r
+\r
+                       //sub-collections\r
+                       nameSpace = AlgaTerraCollectionImport.NAMESPACE_SUBCOLLECTION;\r
+                       cdmClass = Collection.class;\r
+                       idSet = collectionIdSet;\r
+                       Map<String, Collection> subCollectionMap = (Map<String, Collection>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, subCollectionMap);\r
+\r
+                       //terms\r
+                       nameSpace = AlgaTerraEcoFactImport.TERMS_NAMESPACE;\r
+                       cdmClass = FieldObservation.class;\r
+                       idSet = termsIdSet;\r
+                       Map<String, DefinedTermBase> termMap = (Map<String, DefinedTermBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, termMap);\r
+                       \r
+               } catch (SQLException e) {\r
+                       throw new RuntimeException(e);\r
+               }\r
+               return result;\r
+       }\r
+\r
+\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)\r
+        */\r
+       @Override\r
+       protected boolean doCheck(BerlinModelImportState state){\r
+               IOValidator<BerlinModelImportState> validator = new AlgaTerraSpecimenImportValidator();\r
+               return validator.validate(state);\r
+       }\r
+\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)\r
+        */\r
+       protected boolean isIgnore(BerlinModelImportState state){\r
+               return ! ((AlgaTerraImportState)state).getAlgaTerraConfigurator().isDoEcoFacts();\r
+       }\r
+       \r
+}\r
diff --git a/app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraFactEcologyImport.java b/app-import/src/main/java/eu/etaxonomy/cdm/io/algaterra/AlgaTerraFactEcologyImport.java
new file mode 100644 (file)
index 0000000..6488ff1
--- /dev/null
@@ -0,0 +1,429 @@
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\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.io.algaterra;\r
+\r
+import java.sql.Date;\r
+import java.sql.ResultSet;\r
+import java.sql.SQLException;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.apache.commons.lang.StringUtils;\r
+import org.apache.log4j.Logger;\r
+import org.springframework.stereotype.Component;\r
+\r
+import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;\r
+import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeCacheStrategy;\r
+import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade.DerivedUnitType;\r
+import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeNotSupportedException;\r
+import eu.etaxonomy.cdm.io.algaterra.validation.AlgaTerraSpecimenImportValidator;\r
+import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator;\r
+import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;\r
+import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelReferenceImport;\r
+import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTaxonImport;\r
+import eu.etaxonomy.cdm.io.common.IOValidator;\r
+import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;\r
+import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+import eu.etaxonomy.cdm.model.common.TimePeriod;\r
+import eu.etaxonomy.cdm.model.description.Feature;\r
+import eu.etaxonomy.cdm.model.description.IndividualsAssociation;\r
+import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
+import eu.etaxonomy.cdm.model.name.BotanicalName;\r
+import eu.etaxonomy.cdm.model.name.Rank;\r
+import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;\r
+import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;\r
+import eu.etaxonomy.cdm.model.occurrence.DerivedUnitBase;\r
+import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;\r
+import eu.etaxonomy.cdm.model.occurrence.FieldObservation;\r
+import eu.etaxonomy.cdm.model.occurrence.Fossil;\r
+import eu.etaxonomy.cdm.model.occurrence.LivingBeing;\r
+import eu.etaxonomy.cdm.model.occurrence.Observation;\r
+import eu.etaxonomy.cdm.model.occurrence.Specimen;\r
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;\r
+import eu.etaxonomy.cdm.model.reference.Reference;\r
+import eu.etaxonomy.cdm.model.taxon.Taxon;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
+\r
+\r
+/**\r
+ * Alga Terra Import für den Fact mit FactId =202 (Ecology)\r
+ * @author a.mueller\r
+ * @created 01.09.2012\r
+ */\r
+@Component\r
+public class AlgaTerraFactEcologyImport  extends AlgaTerraSpecimenImportBase {\r
+       private static final Logger logger = Logger.getLogger(AlgaTerraFactEcologyImport.class);\r
+\r
+       \r
+       private static int modCount = 5000;\r
+       private static final String pluralString = "determinations";\r
+       private static final String dbTableName = "Fact"; \r
+\r
+\r
+       public AlgaTerraFactEcologyImport(){\r
+               super(dbTableName, pluralString);\r
+       }\r
+       \r
+       \r
+       \r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getIdQuery()\r
+        */\r
+       @Override\r
+       protected String getIdQuery(BerlinModelImportState state) {\r
+               String result = " SELECT f.factId " + \r
+                               " FROM Fact f LEFT JOIN PTaxon pt ON f.PTNameFk = pt.PTNameFk AND f.PTRefFk = pt.PTRefFk " \r
+                               + " WHERE f.FactCategoryFk = 202 "\r
+                               + " ORDER BY pt.RIdentifier, f.FactId ";\r
+               return result;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)\r
+        */\r
+       @Override\r
+       protected String getRecordQuery(BerlinModelImportConfigurator config) {\r
+                       String strQuery =   \r
+            " SELECT pt.RIdentifier as taxonId, f.* " + \r
+            " FROM Fact f " + \r
+                 " LEFT JOIN PTaxon pt ON f.PTNameFk =pt.PTNameFk AND f.PTRefFk = pt.PTRefFk " +\r
+             " WHERE f.FactCategoryFk = 202 AND (f.FactId IN (" + ID_LIST_TOKEN + ")  )"  \r
+            + " ORDER BY pt.RIdentifier, f.FactId "\r
+            ;\r
+               return strQuery;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)\r
+        */\r
+       public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState bmState) {\r
+               boolean success = true;\r
+               \r
+               AlgaTerraImportState state = (AlgaTerraImportState)bmState;\r
+               Set<TaxonBase> taxaToSave = new HashSet<TaxonBase>();\r
+               \r
+               Map<String, TaxonBase> taxonMap = (Map<String, TaxonBase>) partitioner.getObjectMap(BerlinModelTaxonImport.NAMESPACE);\r
+               Map<String, DerivedUnitBase> ecoFactDerivedUnitMap = (Map<String, DerivedUnitBase>) partitioner.getObjectMap(ECO_FACT_DERIVED_UNIT_NAMESPACE);\r
+               \r
+               ResultSet rs = partitioner.getResultSet();\r
+\r
+               try {\r
+                       \r
+                       int i = 0;\r
+\r
+                       //for each reference\r
+            while (rs.next()){\r
+                \r
+                       if ((i++ % modCount) == 0 && i!= 1 ){ logger.info(pluralString + " handled: " + (i-1));}\r
+                               \r
+                               Integer taxonId = nullSafeInt(rs, "taxonId");\r
+                               int factId = rs.getInt("FactId");\r
+                               Integer ecoFactId = nullSafeInt(rs, "ExtensionFk");\r
+                               String recordBasis = rs.getString("RecordBasis");\r
+                               \r
+                               \r
+                               try {\r
+                                       \r
+                                       //source ref\r
+                                       Reference<?> sourceRef = state.getTransactionalSourceReference();\r
+                               \r
+                                       DerivedUnitBase<?> ecoFact = ecoFactDerivedUnitMap.get(String.valueOf(ecoFactId));\r
+                                       \r
+                                       \r
+                                       //description element\r
+                                       if (taxonId != null){\r
+                                               Taxon taxon = getTaxon(state, taxonId, taxonMap, factId);               \r
+                                               \r
+                                               if(taxon != null){\r
+                                                       DerivedUnitBase identifiedSpecimen = makeIdentifiedSpecimen(ecoFact, recordBasis);\r
+                                                       \r
+                                                       makeDetermination(state, rs, taxon, identifiedSpecimen, factId, partitioner);\r
+                                                                                                       \r
+                                                       makeIndividualsAssociation(state, taxon, sourceRef, identifiedSpecimen);\r
+                                                       \r
+                                                       this.doIdCreatedUpdatedNotes(state, identifiedSpecimen, rs, factId, getDerivedUnitNameSpace());\r
+\r
+                                                       identifiedSpecimen.setCacheStrategy(new DerivedUnitFacadeCacheStrategy());\r
+                                                       taxaToSave.add(taxon);\r
+                                               }\r
+                                       }else{\r
+                                               logger.warn("No taxon defined for ecology fact: " +  factId);\r
+                                       }\r
+                                       \r
+\r
+                               } catch (Exception e) {\r
+                                       logger.warn("Exception in FactEcology: FactId " + factId + ". " + e.getMessage());\r
+                                       e.printStackTrace();\r
+                               } \r
+                \r
+            }\r
+           \r
+//            logger.warn("Specimen: " + countSpecimen + ", Descriptions: " + countDescriptions );\r
+\r
+                       logger.warn("Taxa to save: " + taxaToSave.size());\r
+                       getTaxonService().save(taxaToSave);     \r
+                       \r
+                       return success;\r
+               } catch (SQLException e) {\r
+                       logger.error("SQLException:" +  e);\r
+                       return false;\r
+               }\r
+       }\r
+       \r
+       private void makeIndividualsAssociation(AlgaTerraImportState state, Taxon taxon, Reference<?> sourceRef, DerivedUnitBase<?> identifiedSpecimen){\r
+               TaxonDescription taxonDescription = getTaxonDescription(state, taxon, sourceRef);\r
+               IndividualsAssociation indAssociation = IndividualsAssociation.NewInstance();\r
+               Feature feature = makeFeature(identifiedSpecimen);\r
+               indAssociation.setAssociatedSpecimenOrObservation(identifiedSpecimen);\r
+               indAssociation.setFeature(feature);\r
+               taxonDescription.addElement(indAssociation);    \r
+       }\r
+       \r
+       private void makeDetermination(AlgaTerraImportState state, ResultSet rs, Taxon taxon, DerivedUnitBase<?> identifiedSpecimen, int factId, ResultSetPartitioner partitioner) throws SQLException {\r
+               Date identifiedWhen = rs.getDate("IdentifiedWhen");\r
+               Date identifiedWhenEnd = rs.getDate("IdentiedWhenEnd");\r
+               boolean restrictedFlag = rs.getBoolean("RestrictedFlag");\r
+               //Team FK ist immer null\r
+               String identifiedBy = rs.getString("IdentifiedBy");\r
+               String identificationReference = rs.getString("IdentificationReference");\r
+               Integer refFk = nullSafeInt(rs, "IdentifidationRefFk");\r
+               \r
+               \r
+               DeterminationEvent determination = DeterminationEvent.NewInstance(taxon, identifiedSpecimen);\r
+               TimePeriod determinationPeriod = TimePeriod.NewInstance(identifiedWhen, identifiedWhenEnd);\r
+               determination.setTimeperiod(determinationPeriod);\r
+               determination.setPreferredFlag(! restrictedFlag);\r
+               //TODO \r
+               \r
+               TeamOrPersonBase<?> author = getAuthor(identifiedBy);\r
+               determination.setDeterminer(author);\r
+               if (refFk != null){\r
+                       Map<String, Reference> biblioRefMap = (Map<String, Reference>) partitioner.getObjectMap(BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE);\r
+                       Map<String, Reference> nomRefMap = (Map<String, Reference>) partitioner.getObjectMap(BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE);\r
+                       \r
+                       Reference<?> ref = getReferenceOnlyFromMaps(biblioRefMap, nomRefMap, String.valueOf(refFk));\r
+                       determination.addReference(ref);\r
+               }else{\r
+                       //IdentificationReference is not to be handled according to Henning\r
+                       if (StringUtils.isNotBlank(identificationReference)){\r
+                               logger.warn("IdentificationReference exists without IdentificationRefFk. FactId: "+  factId);\r
+                       }\r
+               }\r
+               \r
+               \r
+               \r
+               //TODO\r
+//             kind of identification, IdentificationUncertainty, IdentificationMethod, \r
+               \r
+               \r
+       }\r
+\r
+\r
+\r
+       private DerivedUnitBase<?> makeIdentifiedSpecimen(DerivedUnitBase<?> ecoFact, String recordBasis) {\r
+               //TODO event type\r
+               DerivationEvent event = DerivationEvent.NewInstance();\r
+               DerivedUnitType derivedUnitType = makeDerivedUnitType(recordBasis);\r
+               if (derivedUnitType == null){\r
+                       logger.warn("NULL");\r
+               }\r
+               \r
+               DerivedUnitBase<?> result = derivedUnitType.getNewDerivedUnitInstance();\r
+               result.setDerivedFrom(event);\r
+               ecoFact.addDerivationEvent(event);\r
+               \r
+               return result;\r
+       }\r
+\r
+\r
+\r
+       protected String getDerivedUnitNameSpace(){\r
+               return FACT_ECOLOGY_NAMESPACE;\r
+       }\r
+       \r
+       protected String getFieldObservationNameSpace(){\r
+               return null;\r
+       }\r
+\r
+\r
+\r
+\r
+       /**\r
+        * @param state\r
+        * @param ecoFactId\r
+        * @param derivedUnitMap\r
+        * @param type \r
+        * @return\r
+        */\r
+       private DerivedUnitFacade getDerivedUnit(AlgaTerraImportState state, int ecoFactId, Map<String, DerivedUnit> derivedUnitMap, DerivedUnitType type) {\r
+               String key = String.valueOf(ecoFactId);\r
+               DerivedUnit derivedUnit = derivedUnitMap.get(key);\r
+               DerivedUnitFacade facade;\r
+               if (derivedUnit == null){\r
+                       facade = DerivedUnitFacade.NewInstance(type);\r
+                       derivedUnitMap.put(key, derivedUnit);\r
+               }else{\r
+                       try {\r
+                               facade = DerivedUnitFacade.NewInstance(derivedUnit);\r
+                       } catch (DerivedUnitFacadeNotSupportedException e) {\r
+                               logger.error(e.getMessage());\r
+                               facade = DerivedUnitFacade.NewInstance(type);\r
+                       }\r
+               }\r
+               \r
+               return facade;\r
+       }\r
+       \r
+       private Feature makeFeature(SpecimenOrObservationBase unit) {\r
+               if (unit.isInstanceOf(DerivedUnit.class)){\r
+                       return Feature.INDIVIDUALS_ASSOCIATION();\r
+               }else if (unit.isInstanceOf(FieldObservation.class) || unit.isInstanceOf(Observation.class) ){\r
+                       return Feature.OBSERVATION();\r
+               }else if (unit.isInstanceOf(Fossil.class) || unit.isInstanceOf(LivingBeing.class) || unit.isInstanceOf(Specimen.class )){\r
+                       return Feature.SPECIMEN();\r
+               }\r
+               logger.warn("No feature defined for derived unit class: " + unit.getClass().getSimpleName());\r
+               return null;\r
+       }\r
+\r
+\r
+       private DerivedUnitType makeDerivedUnitType(String recordBasis) {\r
+               DerivedUnitType result = null;\r
+               if (StringUtils.isBlank(recordBasis)){\r
+                       result = DerivedUnitType.DerivedUnit;\r
+               } else if (recordBasis.equalsIgnoreCase("FossileSpecimen")){\r
+                       result = DerivedUnitType.Fossil;\r
+               }else if (recordBasis.equalsIgnoreCase("Observation")){\r
+                       result = DerivedUnitType.Observation;\r
+               }else if (recordBasis.equalsIgnoreCase("HumanObservation")){\r
+                       result = DerivedUnitType.Observation;\r
+               }else if (recordBasis.equalsIgnoreCase("Literature")){\r
+                       logger.warn("Literature record basis not yet supported");\r
+                       result = DerivedUnitType.DerivedUnit;\r
+               }else if (recordBasis.equalsIgnoreCase("LivingSpecimen")){\r
+                       result = DerivedUnitType.LivingBeing;\r
+               }else if (recordBasis.equalsIgnoreCase("LivingCulture")){\r
+                       logger.warn("LivingCulture record basis not yet supported");\r
+                       result = DerivedUnitType.DerivedUnit;\r
+               }else if (recordBasis.equalsIgnoreCase("MachineObservation")){\r
+                       logger.warn("MachineObservation record basis not yet supported");\r
+                       result = DerivedUnitType.Observation;\r
+               }else if (recordBasis.equalsIgnoreCase("PreservedSpecimen")){\r
+                       result = DerivedUnitType.Specimen;\r
+               }\r
+               return result;\r
+       }\r
+\r
+\r
+\r
+       /**\r
+        * @param state\r
+        * @param newTaxonId\r
+        * @param taxonMap\r
+        * @param factId\r
+        * @return\r
+        */\r
+       private Taxon getTaxon(AlgaTerraImportState state, int taxonId, Map<String, TaxonBase> taxonMap, int factId) {\r
+               TaxonBase<?> taxonBase = taxonMap.get(String.valueOf(taxonId));\r
+               \r
+               //TODO for testing\r
+               if (taxonBase == null && ! state.getConfig().isDoTaxa()){\r
+                       taxonBase = Taxon.NewInstance(BotanicalName.NewInstance(Rank.SPECIES()), null);\r
+               }\r
+               \r
+               Taxon taxon;\r
+               if ( taxonBase instanceof Taxon ) {\r
+                       taxon = (Taxon) taxonBase;\r
+               } else if (taxonBase != null) {\r
+                       logger.warn("TaxonBase (" + taxonId + ") for Fact(Specimen) with factId " + factId + " was not of type Taxon but: " + taxonBase.getClass().getSimpleName());\r
+                       return null;\r
+               } else {\r
+                       logger.warn("TaxonBase (" + taxonId + ") for Fact(Specimen) with factId " + factId + " is null.");\r
+                       return null;\r
+               }\r
+               return taxon;\r
+       }\r
+       \r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)\r
+        */\r
+       public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs) {\r
+               String nameSpace;\r
+               Class cdmClass;\r
+               Set<String> idSet;\r
+               Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();\r
+               \r
+               try{\r
+                       Set<String> taxonIdSet = new HashSet<String>();\r
+                       Set<String> extensionFkSet = new HashSet<String>();\r
+                       Set<String> referenceIdSet = new HashSet<String>();\r
+                       \r
+                       while (rs.next()){\r
+                               handleForeignKey(rs, taxonIdSet, "taxonId");\r
+                               handleForeignKey(rs, extensionFkSet, "extensionFk");\r
+                               handleForeignKey(rs, referenceIdSet, "IdentifidationRefFk");\r
+                       }\r
+                       \r
+                       //taxon map\r
+                       nameSpace = BerlinModelTaxonImport.NAMESPACE;\r
+                       cdmClass = TaxonBase.class;\r
+                       idSet = taxonIdSet;\r
+                       Map<String, TaxonBase> objectMap = (Map<String, TaxonBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, objectMap);\r
+\r
+                       //derived unit map\r
+                       nameSpace = AlgaTerraFactEcologyImport.ECO_FACT_DERIVED_UNIT_NAMESPACE;\r
+                       cdmClass = DerivedUnitBase.class;\r
+                       idSet = extensionFkSet;\r
+                       Map<String, DerivedUnitBase> derivedUnitMap = (Map<String, DerivedUnitBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, derivedUnitMap);\r
+\r
+                       //nom reference map\r
+                       nameSpace = BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE;\r
+                       cdmClass = Reference.class;\r
+                       idSet = referenceIdSet;\r
+                       Map<String, Reference> nomReferenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, nomReferenceMap);\r
+\r
+                       //biblio reference map\r
+                       nameSpace = BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE;\r
+                       cdmClass = Reference.class;\r
+                       idSet = referenceIdSet;\r
+                       Map<String, Reference> biblioReferenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, biblioReferenceMap);\r
+\r
+                       \r
+               } catch (SQLException e) {\r
+                       throw new RuntimeException(e);\r
+               }\r
+               return result;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)\r
+        */\r
+       @Override\r
+       protected boolean doCheck(BerlinModelImportState state){\r
+               IOValidator<BerlinModelImportState> validator = new AlgaTerraSpecimenImportValidator();\r
+               return validator.validate(state);\r
+       }\r
+\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)\r
+        */\r
+       protected boolean isIgnore(BerlinModelImportState state){\r
+               return ! ((AlgaTerraImportState)state).getAlgaTerraConfigurator().isDoEcoFacts();\r
+       }\r
+       \r
+}\r
index d0bbf5a6b137bb4dad1068e9e17dbe6dff159a15..127adf58faa8780376a22f3b46dd7419f7ea8659 100644 (file)
@@ -6,29 +6,20 @@ package eu.etaxonomy.cdm.io.algaterra;
 import eu.etaxonomy.cdm.database.ICdmDataSource;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelAuthorImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelAuthorTeamImport;\r
-import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelCommonNamesImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelFactsImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator;\r
-import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;\r
-import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelNameFactsImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelNameStatusImport;\r
-import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelOccurrenceImport;\r
-import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelOccurrenceSourceImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelRefDetailImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelReferenceImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTaxonImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTaxonNameImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTaxonNameRelationImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTaxonRelationImport;\r
-import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelTypesImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelUserImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelWebMarkerCategoryImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelWebMarkerImport;\r
 import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelGeneralImportValidator;\r
-import eu.etaxonomy.cdm.io.common.DbImportStateBase;\r
-import eu.etaxonomy.cdm.io.common.ImportStateBase;\r
 import eu.etaxonomy.cdm.io.common.Source;\r
-import eu.etaxonomy.cdm.model.name.NomenclaturalCode;\r
 \r
 /**\r
  * @author pesiimport\r
@@ -37,6 +28,7 @@ import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
 public class AlgaTerraImportConfigurator extends BerlinModelImportConfigurator {\r
 \r
        private boolean doEcoFacts = true;\r
+       private boolean doFactEcology = true;\r
        \r
        private boolean doImages = true;\r
        \r
@@ -70,11 +62,13 @@ public class AlgaTerraImportConfigurator extends BerlinModelImportConfigurator {
                                , BerlinModelWebMarkerImport.class\r
                                \r
                                , AlgaTerraCollectionImport.class\r
-                               , AlgaTerraSpecimenImport.class\r
+                               , AlgaTerraEcoFactImport.class\r
+                               , AlgaTerraFactEcologyImport.class\r
                                , AlgaTerraTypeImport.class\r
                                , AlgaTerraTypeImagesImport.class\r
                                , AlgaTerraVoucherImagesImport.class\r
                                , AlgaTerraSiteImagesImport.class\r
+                               , AlgaTerraPictureImport.class\r
                                \r
                };      \r
                \r
@@ -113,5 +107,13 @@ public class AlgaTerraImportConfigurator extends BerlinModelImportConfigurator {
                this.doImages = doImages;\r
        }\r
 \r
+       public boolean isDoFactEcology() {\r
+               return doFactEcology;\r
+       }\r
+\r
+       public void setDoFactEcology(boolean doFactEcology) {\r
+               this.doFactEcology = doFactEcology;\r
+       }\r
+\r
 \r
 }\r
index 186f348095d942f47c94b37c37a91a95fe8b4730..b479661b8490f5a1c5652272e9b918097ff6cb4f 100644 (file)
@@ -17,7 +17,6 @@ import java.util.UUID;
 import org.apache.log4j.Logger;\r
 \r
 import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;\r
-import eu.etaxonomy.cdm.model.description.StatisticalMeasure;\r
 \r
 /**\r
  * @author a.mueller\r
@@ -30,7 +29,6 @@ public class AlgaTerraImportState extends BerlinModelImportState{
        private static final Logger logger = Logger.getLogger(AlgaTerraImportState.class);\r
 \r
        private boolean specimenVocabulariesCreated = false;\r
-       private boolean currentFieldObservationNotNew = false;\r
        private Map<String, UUID> parameterFeatureUuidMap = new HashMap<String, UUID>(); \r
        \r
        public AlgaTerraImportState(AlgaTerraImportConfigurator config) {\r
@@ -49,15 +47,6 @@ public class AlgaTerraImportState extends BerlinModelImportState{
                this.specimenVocabulariesCreated = specimenVocabulariesCreated;\r
        }\r
 \r
-       public boolean isCurrentFieldObservationNotNew() {\r
-               return currentFieldObservationNotNew;\r
-       }\r
-\r
-       public void setCurrentFieldObservationNotNew(\r
-                       boolean currentFieldObservationNotNew) {\r
-               this.currentFieldObservationNotNew = currentFieldObservationNotNew;\r
-       }\r
-\r
        public UUID getParameterFeatureUuid(String key) {\r
                return parameterFeatureUuidMap.get(key);\r
        }\r
index ece745c9240dea7af0a5a15d091a3da60f00f6cb..f5ef240994c5740c0f83eea07490bca356bac5c1 100644 (file)
@@ -25,18 +25,22 @@ import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase;
 import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;\r
 import eu.etaxonomy.cdm.io.common.Source;\r
 import eu.etaxonomy.cdm.model.agent.Team;\r
+import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;\r
 import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;\r
 import eu.etaxonomy.cdm.model.common.TimePeriod;\r
 import eu.etaxonomy.cdm.model.description.DescriptionBase;\r
 import eu.etaxonomy.cdm.model.description.Feature;\r
 import eu.etaxonomy.cdm.model.description.SpecimenDescription;\r
 import eu.etaxonomy.cdm.model.description.State;\r
+import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
 import eu.etaxonomy.cdm.model.location.NamedArea;\r
 import eu.etaxonomy.cdm.model.location.Point;\r
 import eu.etaxonomy.cdm.model.location.ReferenceSystem;\r
 import eu.etaxonomy.cdm.model.location.TdwgArea;\r
 import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;\r
 import eu.etaxonomy.cdm.model.occurrence.Collection;\r
+import eu.etaxonomy.cdm.model.reference.Reference;\r
+import eu.etaxonomy.cdm.model.taxon.Taxon;\r
 \r
 /**\r
  * @author a.mueller\r
@@ -45,10 +49,12 @@ import eu.etaxonomy.cdm.model.occurrence.Collection;
 public abstract class AlgaTerraSpecimenImportBase extends BerlinModelImportBase{\r
        private static final Logger logger = Logger.getLogger(AlgaTerraSpecimenImportBase.class);\r
 \r
-       public static final String ECO_FACT_FIELD_OBSERVATION_NAMESPACE = "EcoFact";\r
-       public static final String ECO_FACT_DERIVED_UNIT_NAMESPACE = "EcoFact";\r
+       public static final String ECO_FACT_FIELD_OBSERVATION_NAMESPACE = "EcoFact_FieldObservation";\r
+       public static final String ECO_FACT_DERIVED_UNIT_NAMESPACE = "EcoFact_DerivedUnit";\r
        public static final String TYPE_SPECIMEN_FIELD_OBSERVATION_NAMESPACE = "TypeSpecimen_FieldObservation";\r
        public static final String TYPE_SPECIMEN_DERIVED_UNIT_NAMESPACE = "TypeSpecimen_DerivedUnit";\r
+       public static final String FACT_ECOLOGY_NAMESPACE = "Fact(Ecology)";\r
+       \r
        \r
        public static final String TERMS_NAMESPACE = "ALGA_TERRA_TERMS";\r
        \r
@@ -156,7 +162,7 @@ public abstract class AlgaTerraSpecimenImportBase extends BerlinModelImportBase{
                return "Locality";\r
        }\r
        \r
-       protected void handleSingleSpecimen(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state, ResultSetPartitioner partitioner) throws SQLException {\r
+       protected void handleFieldObservationSpecimen(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state, ResultSetPartitioner partitioner) throws SQLException {\r
                //FIXME missing fields #3084, #3085, #3080\r
                try {\r
                        \r
@@ -177,9 +183,6 @@ public abstract class AlgaTerraSpecimenImportBase extends BerlinModelImportBase{
                        Date collectionDateStart = rs.getDate("CollectionDate");\r
                        Date collectionDateEnd = rs.getDate("CollectionDateEnd");\r
                        \r
-                       Integer collectionFk = nullSafeInt(rs,"CollectionFk");\r
-                       \r
-                       \r
                        //location\r
                        facade.setLocality(locality);\r
                                \r
@@ -225,37 +228,52 @@ public abstract class AlgaTerraSpecimenImportBase extends BerlinModelImportBase{
                        \r
                        //areas\r
                        makeAreas(state, rs, facade);\r
-                       \r
-                       //collection\r
-                       if (collectionFk != null){\r
-                               Collection subCollection = state.getRelatedObject(AlgaTerraCollectionImport.NAMESPACE_SUBCOLLECTION, String.valueOf(collectionFk), Collection.class);\r
-                               if (subCollection != null){\r
-                                       facade.setCollection(subCollection);\r
-                               }else{\r
-                                       Collection collection = state.getRelatedObject(AlgaTerraCollectionImport.NAMESPACE_COLLECTION, String.valueOf(collectionFk), Collection.class);\r
-                                       facade.setCollection(collection);\r
-                               }\r
-                       }\r
-                       \r
+\r
                        //notes\r
                        //TODO is this an annotation on field observation or on the derived unit?\r
                        \r
-                       //TODO id, created for fact +  ecoFact\r
-                       //      this.doIdCreatedUpdatedNotes(state, descriptionElement, rs, id, namespace);\r
+                       //id, created, updated, notes\r
                        if (unitId != null){\r
-                               this.doIdCreatedUpdatedNotes(state, facade.innerDerivedUnit(), rs, unitId, getDerivedUnitNameSpace());\r
+                               this.doIdCreatedUpdatedNotes(state, facade.innerFieldObservation(), rs, unitId, getFieldObservationNameSpace());\r
                        }else{\r
-                               logger.warn("Specimen has no unitId: " +  facade.innerDerivedUnit() + ": " + getDerivedUnitNameSpace());\r
+                               logger.warn("FieldObservation has no unitId: " +  facade.innerFieldObservation() + ": " + getFieldObservationNameSpace());\r
                        }\r
-                       \r
-                       \r
                } catch (Exception e) {\r
                        throw new RuntimeException(e);\r
                }\r
        \r
        }\r
        \r
+       protected void handleFirstDerivedSpecimen(ResultSet rs, DerivedUnitFacade facade, AlgaTerraImportState state, ResultSetPartitioner partitioner) throws SQLException {\r
+               Integer unitId = nullSafeInt(rs, "unitId");\r
+               Integer collectionFk = nullSafeInt(rs,"CollectionFk");\r
+               \r
+               //collection\r
+               if (collectionFk != null){\r
+                       Collection subCollection = state.getRelatedObject(AlgaTerraCollectionImport.NAMESPACE_SUBCOLLECTION, String.valueOf(collectionFk), Collection.class);\r
+                       if (subCollection != null){\r
+                               facade.setCollection(subCollection);\r
+                       }else{\r
+                               Collection collection = state.getRelatedObject(AlgaTerraCollectionImport.NAMESPACE_COLLECTION, String.valueOf(collectionFk), Collection.class);\r
+                               facade.setCollection(collection);\r
+                       }\r
+               }\r
+               \r
+               //TODO id, created for fact +  ecoFact\r
+               //      this.doIdCreatedUpdatedNotes(state, descriptionElement, rs, id, namespace);\r
+               if (unitId != null){\r
+                       this.doIdCreatedUpdatedNotes(state, facade.innerDerivedUnit(), rs, unitId, getDerivedUnitNameSpace());\r
+               }else{\r
+                       logger.warn("Specimen has no unitId: " +  facade.innerDerivedUnit() + ": " + getDerivedUnitNameSpace());\r
+               }\r
+       }\r
+               \r
+       \r
+       \r
        protected abstract String getDerivedUnitNameSpace();\r
+       \r
+       protected abstract String getFieldObservationNameSpace();\r
+       \r
 \r
        protected DescriptionBase getFieldObservationDescription(DerivedUnitFacade facade) {\r
                Set<DescriptionBase> descriptions = facade.innerFieldObservation().getDescriptions();\r
@@ -355,10 +373,42 @@ public abstract class AlgaTerraSpecimenImportBase extends BerlinModelImportBase{
        \r
 \r
        private void handleCollectorTeam(AlgaTerraImportState state, DerivedUnitFacade facade, ResultSet rs) throws SQLException {\r
-               // FIXME parsen\r
                String collector = rs.getString("Collector");\r
-               Team team = Team.NewTitledInstance(collector, collector);\r
-               facade.setCollector(team);\r
+               TeamOrPersonBase<?> author = getAuthor(collector);\r
+               facade.setCollector(author);\r
+       }\r
+\r
+       /**\r
+        * @param facade\r
+        * @param collector\r
+        */\r
+       protected TeamOrPersonBase<?> getAuthor(String author) {\r
+               // FIXME TODO parsen und deduplizieren\r
+               Team team = Team.NewTitledInstance(author, author);\r
+               return team;\r
+       }\r
+       \r
+\r
+       /**\r
+        * Use same TaxonDescription if two records belong to the same taxon \r
+        * @param state \r
+        * @param newTaxonId\r
+        * @param oldTaxonId\r
+        * @param oldDescription\r
+        * @param taxonMap\r
+        * @return\r
+        */\r
+       protected TaxonDescription getTaxonDescription(AlgaTerraImportState state, Taxon taxon, Reference<?> sourceSec){\r
+               TaxonDescription result = null;\r
+               Set<TaxonDescription> descriptionSet= taxon.getDescriptions();\r
+               if (descriptionSet.size() > 0) {\r
+                       result = descriptionSet.iterator().next(); \r
+               }else{\r
+                       result = TaxonDescription.NewInstance();\r
+                       result.setTitleCache(sourceSec.getTitleCache(), true);\r
+                       taxon.addDescription(result);\r
+               }\r
+               return result;\r
        }\r
 \r
        \r
index bc3ed1bd768dd5ce7740467a43685e4afcf02c25..c0151ca15114273c39c767134fe534baea385f47 100644 (file)
@@ -152,10 +152,14 @@ public class AlgaTerraTypeImport  extends AlgaTerraSpecimenImportBase {
                                        DerivedUnitFacade facade = getDerivedUnit(state, typeSpecimenId, typeSpecimenMap, type, ecoFactMap, ecoFactId);\r
                                        \r
                                        //field observation\r
-                                       handleSingleSpecimen(rs, facade, state, partitioner);\r
+                                       handleFieldObservationSpecimen(rs, facade, state, partitioner);\r
                                        \r
+                                       //TODO devide like in EcoFact (if necessary)\r
                                        handleTypeSpecimenSpecificSpecimen(rs,facade, state);\r
                                        \r
+                                       handleFirstDerivedSpecimen(rs, facade, state, partitioner);\r
+                                       \r
+                                       \r
                                        //Designation\r
                                        TaxonNameBase<?,?> name = getTaxonName(state, taxonNameMap, nameId);\r
                                        SpecimenTypeDesignation designation = SpecimenTypeDesignation.NewInstance();\r
@@ -193,6 +197,10 @@ public class AlgaTerraTypeImport  extends AlgaTerraSpecimenImportBase {
        protected String getDerivedUnitNameSpace(){\r
                return TYPE_SPECIMEN_DERIVED_UNIT_NAMESPACE;\r
        }\r
+       \r
+       protected String getFieldObservationNameSpace(){\r
+               return TYPE_SPECIMEN_FIELD_OBSERVATION_NAMESPACE;\r
+       }\r
 \r
        /**\r
         * @param state \r