package eu.etaxonomy.cdm.io.excel.common;\r
\r
import java.util.ArrayList;\r
+import java.util.HashMap;\r
import java.util.List;\r
+import java.util.Map;\r
import java.util.TreeMap;\r
import java.util.UUID;\r
\r
import org.apache.log4j.Logger;\r
\r
+import eu.etaxonomy.cdm.io.excel.common.ExcelTaxonOrSpecimenImportBase.SourceType;\r
import eu.etaxonomy.cdm.model.common.IdentifiableSource;\r
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;\r
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;\r
public String postfix;\r
}\r
\r
+ \r
+ public class SourceDataHolder{\r
+ private TreeMap<Integer, Map<SourceType, String>> sources = new TreeMap<Integer, Map<SourceType, String>>();\r
+ \r
+ public void putSource(int index, SourceType type, String value){\r
+ Map<SourceType, String> map = sources.get(index);\r
+ if (map == null){\r
+ map = new HashMap<SourceType, String>();\r
+ sources.put(index, map);\r
+ }\r
+ map.put(type, value);\r
+ }\r
+\r
+ public List<Map<SourceType, String>> getSources() {\r
+ return getOrdered(sources);\r
+ }\r
+ }\r
+ \r
\r
\r
// **************************** GETTER / SETTER *********************************/ \r
state.setCurrentRow(row);\r
\r
for (String originalKey: keys) {\r
- KeyValue keyValue = makeKeyValue(record, originalKey);\r
+ KeyValue keyValue = makeKeyValue(record, originalKey, state);\r
if (StringUtils.isBlank(keyValue.value)){\r
continue;\r
}\r
protected class KeyValue{\r
public KeyValue() {}\r
\r
+ //original Key\r
+ public String originalKey;\r
+ //value\r
public String value;\r
+ //atomized key\r
public String key;\r
public String postfix;\r
- public Integer index;\r
- public String ref;\r
- public String refAuthor;\r
- public String refIndex;\r
- public String originalKey;\r
+ public int index = 0;\r
+ public SourceType refType;\r
+ public int refIndex = 0;\r
+ public boolean hasError = false;\r
+ public boolean isKeyData() {\r
+ return (refType == null);\r
+ }\r
+ }\r
+ \r
+ public enum SourceType{\r
+ Author("RefAuthor"),\r
+ Title("RefTitle"),\r
+ Year("RefYear");\r
+ \r
+ String keyName = null;\r
+ private SourceType(String keyName){\r
+ this.keyName = keyName;\r
+ }\r
+ \r
+ static SourceType byKeyName(String str){\r
+ for (SourceType type : SourceType.values()){\r
+ if (type.keyName.equalsIgnoreCase(str)){\r
+ return type;\r
+ } \r
+ }\r
+ return null;\r
+ }\r
+ \r
+ static boolean isKeyName(String str){\r
+ return (byKeyName(str) != null);\r
+ }\r
}\r
\r
\r
/**\r
* @param record\r
* @param originalKey\r
+ * @param state \r
* @param keyValue\r
* @return\r
*/\r
- protected KeyValue makeKeyValue(HashMap<String, String> record, String originalKey) {\r
+ protected KeyValue makeKeyValue(HashMap<String, String> record, String originalKey, STATE state) {\r
KeyValue keyValue = new KeyValue();\r
keyValue.originalKey = originalKey;\r
String indexedKey = CdmUtils.removeDuplicateWhitespace(originalKey.trim()).toString();\r
String[] split = indexedKey.split("_");\r
- keyValue.key = split[0];\r
- if (split.length > 1){\r
- for (int i = 1 ; i < split.length ; i++ ){\r
- String indexString = split[i];\r
- if (isInteger(indexString)){\r
- keyValue.index = Integer.valueOf(indexString);\r
- }else{\r
- keyValue.postfix = split[i];\r
+ int current = 0;\r
+ //key\r
+ keyValue.key = split[current++];\r
+ //postfix\r
+ if (split.length > current && ! isRefType(split[current]) && ! isInteger(split[current]) ){\r
+ keyValue.postfix = split[current++]; \r
+ }\r
+ //index\r
+ if (split.length > current && isInteger(split[current]) ){\r
+ keyValue.index = Integer.valueOf(split[current++]); \r
+ }else{\r
+ keyValue.index = 0;\r
+ }\r
+ //source\r
+ if (split.length > current){\r
+ //refType\r
+ if (isRefType(split[current])){\r
+ String refTypeStr = split[current++];\r
+ keyValue.refType = SourceType.byKeyName(refTypeStr);\r
+ if (keyValue.refType == null){\r
+ String message = "Unmatched source key: " + refTypeStr;\r
+ fireWarningEvent(message, state, 10);\r
+ logger.warn(message);\r
}\r
+ }else {\r
+ String message = "RefType expected at %d position of key. But %s is no valid reftype";\r
+ message = String.format(message, current, split[current]);\r
+ fireWarningEvent(message, state, 10);\r
+ logger.warn(message);\r
+ keyValue.hasError = true;\r
}\r
+ //ref index\r
+ if (split.length > current){\r
+ if (isInteger(split[current])){\r
+ keyValue.refIndex = Integer.valueOf(split[current++]); \r
+ }else{\r
+ String message = "Ref index expected at position %d of key. But %s is no valid reftype";\r
+ message = String.format(message, current, split[current]);\r
+ fireWarningEvent(message, state, 10);\r
+ logger.warn(message);\r
+ keyValue.hasError = true;\r
+ }\r
+ }else {\r
+ keyValue.refIndex = 0;\r
+ }\r
+ \r
+ }\r
+ if (split.length > current){\r
+ String message = "Key has unexpected part at position %d of key. %s (and following parts) can not be handled";\r
+ message = String.format(message, current, split[current]);\r
+ fireWarningEvent(message, state, 10);\r
+ logger.warn(message);\r
+ keyValue.hasError = true;\r
}\r
\r
//TODO shouldn't we use originalKey here??\r
}\r
\r
\r
+ private boolean isRefType(String string) {\r
+ return SourceType.isKeyName(string);\r
+ }\r
+\r
+\r
private boolean handleBaseColumn(KeyValue keyValue, ExcelRowBase row) {\r
String key = keyValue.key;\r
String value = keyValue.value;\r
import java.util.Arrays;\r
import java.util.HashSet;\r
import java.util.List;\r
+import java.util.Map;\r
import java.util.Set;\r
import java.util.UUID;\r
\r
\r
import eu.etaxonomy.cdm.api.service.pager.Pager;\r
import eu.etaxonomy.cdm.common.CdmUtils;\r
+import eu.etaxonomy.cdm.io.excel.common.ExcelRowBase.SourceDataHolder;\r
+import eu.etaxonomy.cdm.model.agent.Team;\r
import eu.etaxonomy.cdm.model.common.CdmBase;\r
import eu.etaxonomy.cdm.model.common.DefinedTermBase;\r
+import eu.etaxonomy.cdm.model.common.DescriptionElementSource;\r
import eu.etaxonomy.cdm.model.common.Language;\r
+import eu.etaxonomy.cdm.model.common.TimePeriod;\r
import eu.etaxonomy.cdm.model.description.CommonTaxonName;\r
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
import eu.etaxonomy.cdm.model.description.Distribution;\r
import eu.etaxonomy.cdm.model.name.Rank;\r
import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
import eu.etaxonomy.cdm.model.reference.Reference;\r
+import eu.etaxonomy.cdm.model.reference.ReferenceFactory;\r
import eu.etaxonomy.cdm.model.taxon.Classification;\r
import eu.etaxonomy.cdm.model.taxon.Synonym;\r
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;\r
}else{\r
Feature feature = CdmBase.deproxy(features.getRecords().get(0), Feature.class);\r
NormalExplicitRow row = state.getCurrentRow();\r
- row.putFeature(feature.getUuid(), keyValue.index == null? 0:keyValue.index, keyValue.value);\r
+ if ( keyValue.isKeyData()){\r
+ row.putFeature(feature.getUuid(), keyValue.index, keyValue.value);\r
+ }else{\r
+ row.putFeatureSource(feature.getUuid(), keyValue.index, keyValue.refType, keyValue.value, keyValue.refIndex);\r
+ }\r
return true;\r
}\r
}\r
Feature feature = CdmBase.deproxy(getTermService().find(featureUuid), Feature.class);\r
List<String> textList = taxonDataHolder.getFeatureTexts(featureUuid);\r
\r
- for (String featureText : textList){\r
+ \r
+ for (int i = 0; i < textList.size(); i++){\r
+ String featureText = textList.get(i);\r
//TODO\r
Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);\r
TaxonDescription td = this.getTaxonDescription(taxon, false, true);\r
TextData textData = TextData.NewInstance(feature);\r
textData.putText(Language.DEFAULT(), featureText);\r
td.addElement(textData);\r
+ \r
+ SourceDataHolder sourceDataHolder = taxonDataHolder.getFeatureTextReferences(featureUuid, i);\r
+ List<Map<SourceType, String>> sourceList = sourceDataHolder.getSources();\r
+ for (Map<SourceType, String> sourceMap : sourceList){\r
+ \r
+ DescriptionElementSource source = DescriptionElementSource.NewInstance();\r
+ //ref\r
+ Reference<?> ref = ReferenceFactory.newGeneric();\r
+ boolean refExists = false; //in case none of the ref fields exists, the ref should not be added\r
+ for (SourceType type : sourceMap.keySet()){\r
+ String value = sourceMap.get(type);\r
+ if (type.equals(SourceType.Author)){\r
+ Team team = Team.NewInstance();\r
+ team.setTitleCache(value, true);\r
+ ref.setAuthorTeam(team);\r
+ }else if (type.equals(SourceType.Title)) {\r
+ ref.setTitle(value);\r
+ }else if (type.equals(SourceType.Year)) {\r
+ ref.setDatePublished(TimePeriod.parseString(value));\r
+ }\r
+ refExists = true;\r
+ }\r
+ if (refExists){\r
+ source.setCitation(ref);\r
+ }\r
+ textData.addSource(source);\r
+ } \r
}\r
}\r
\r
import java.util.UUID;\r
\r
import eu.etaxonomy.cdm.io.excel.common.ExcelRowBase;\r
-import eu.etaxonomy.cdm.model.description.Feature;\r
+import eu.etaxonomy.cdm.io.excel.common.ExcelTaxonOrSpecimenImportBase.SourceType;\r
\r
/**\r
* @author a.babadshanjan\r
\r
private Map<UUID, TreeMap<Integer, String>> featureTexts = new HashMap<UUID, TreeMap<Integer, String>>();\r
\r
+ private Map<UUID, TreeMap<Integer, SourceDataHolder>> textSources = new HashMap<UUID, TreeMap<Integer, SourceDataHolder>>();\r
+\r
+ \r
\r
public NormalExplicitRow() {\r
this.id = 0;\r
}\r
\r
\r
+ public void putFeatureSource(UUID featureUuid, int featureIndex, SourceType refType, String value, int refIndex) {\r
+ //feature Map\r
+ TreeMap<Integer, SourceDataHolder> featureMap = textSources.get(featureUuid);\r
+ if (featureMap == null){\r
+ featureMap = new TreeMap<Integer, SourceDataHolder>();\r
+ textSources.put(featureUuid, featureMap);\r
+ }\r
+ //sourcedText\r
+ SourceDataHolder sourceDataHolder = featureMap.get(featureIndex);\r
+ if (sourceDataHolder == null){\r
+ sourceDataHolder = new SourceDataHolder();\r
+ featureMap.put(featureIndex, sourceDataHolder);\r
+ }\r
+ //\r
+ sourceDataHolder.putSource(refIndex, refType, value);\r
+ }\r
+ \r
+\r
+ public SourceDataHolder getFeatureTextReferences(UUID featureUuid, int index) {\r
+ TreeMap<Integer, SourceDataHolder> textMap = textSources.get(featureUuid);\r
+ if (textMap == null){\r
+ return new SourceDataHolder();\r
+ }else{\r
+ SourceDataHolder sourceMap = textMap.get(index);\r
+ return sourceMap;\r
+ }\r
+ \r
+ }\r
+\r
private List<String> getOrdered(TreeMap<Integer, String> tree) {\r
List<String> result = new ArrayList<String>();\r
for (String distribution : tree.values()){\r
return result;\r
}\r
\r
+\r
+\r
\r
}\r
import eu.etaxonomy.cdm.api.service.ITaxonService;\r
import eu.etaxonomy.cdm.io.common.CdmApplicationAwareDefaultImport;\r
import eu.etaxonomy.cdm.io.common.IImportConfigurator;\r
+import eu.etaxonomy.cdm.model.common.DescriptionElementSource;\r
import eu.etaxonomy.cdm.model.common.Language;\r
import eu.etaxonomy.cdm.model.description.CommonTaxonName;\r
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
import eu.etaxonomy.cdm.model.description.TextData;\r
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;\r
import eu.etaxonomy.cdm.model.name.NonViralName;\r
+import eu.etaxonomy.cdm.model.reference.Reference;\r
import eu.etaxonomy.cdm.model.taxon.Classification;\r
import eu.etaxonomy.cdm.model.taxon.Synonym;\r
import eu.etaxonomy.cdm.model.taxon.Taxon;\r
String text = textData.getText(Language.DEFAULT());\r
String expected = "Description for the first taxon";\r
assertEquals("Unexpected description text", expected, text);\r
- \r
+ assertEquals("Number of source elements should be 1", 1, textData.getSources().size());\r
+ DescriptionElementSource source = textData.getSources().iterator().next();\r
+ Reference ref = source.getCitation();\r
+ assertNotNull("Citation should not be null", ref);\r
+ assertNotNull("AuthorTeam should not be null", ref.getAuthorTeam());\r
+ assertEquals("Source author should be 'Meyer et. al.'", "Meyer et. al.",ref.getAuthorTeam().getTitleCache());\r
+ assertEquals("Publication year should be '1987'", "1987", ref.getYear());\r
\r
}\r
}\r