7df5a0392a708b9906839f3df45db2eefd4e9038
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / sdd / ikeyplus / IkeyPlusImport.java
1 /**
2 * Copyright (C) 2012 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.io.sdd.ikeyplus;
10
11 import java.net.URI;
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18
19 import org.apache.log4j.Logger;
20 import org.codehaus.plexus.util.StringUtils;
21 import org.springframework.stereotype.Component;
22
23 import eu.etaxonomy.cdm.io.common.CdmImportBase;
24 import eu.etaxonomy.cdm.model.common.TermType;
25 import eu.etaxonomy.cdm.model.common.TermVocabulary;
26 import eu.etaxonomy.cdm.model.description.Feature;
27 import eu.etaxonomy.cdm.model.description.KeyStatement;
28 import eu.etaxonomy.cdm.model.description.PolytomousKey;
29 import eu.etaxonomy.cdm.model.description.PolytomousKeyNode;
30 import eu.etaxonomy.cdm.model.name.NonViralName;
31 import eu.etaxonomy.cdm.model.name.Rank;
32 import fr.lis.ikeyplus.IO.SDDSaxParser;
33 import fr.lis.ikeyplus.model.DataSet;
34 import fr.lis.ikeyplus.model.ICharacter;
35 import fr.lis.ikeyplus.model.QuantitativeCharacter;
36 import fr.lis.ikeyplus.model.QuantitativeMeasure;
37 import fr.lis.ikeyplus.model.SingleAccessKeyNode;
38 import fr.lis.ikeyplus.model.SingleAccessKeyTree;
39 import fr.lis.ikeyplus.model.Taxon;
40 import fr.lis.ikeyplus.services.IdentificationKeyGenerator;
41 import fr.lis.ikeyplus.utils.Utils;
42
43 /**
44 * @author andreas
45 * @date Sep 18, 2012
46 *
47 */
48 @Component
49 public class IkeyPlusImport extends CdmImportBase<IkeyPlusImportConfigurator, IkeyPlusImportState>{
50
51 public static final Logger logger = Logger.getLogger(IkeyPlusImport.class);
52
53 private TermVocabulary<Feature> featureVoc;
54
55 private PolytomousKey cdmKey;
56
57 public PolytomousKey getCdmKey() {
58 return cdmKey;
59 }
60
61 public void setCdmKey(PolytomousKey cdmKey) {
62 this.cdmKey = cdmKey;
63 }
64
65 private Map<String, Feature>featureMap = new HashMap<String, Feature>();
66
67 public IkeyPlusImport() {
68
69 }
70
71 /**
72 * @param sddUri
73 * @param utils
74 * @return
75 * @throws Exception
76 */
77 /**
78 * @param sddUri
79 * @param utils
80 * @return
81 * @throws Exception
82 */
83 public PolytomousKey getKey(URI sddUri, Utils utils) throws Exception {
84
85 //TODO move below into configurator
86 utils = new Utils();
87 // utils.setErrorMessage("foobar"); // Don't do it !!!! risk of NPE
88 utils.setFewStatesCharacterFirst(false);
89 utils.setMergeCharacterStatesIfSameDiscrimination(false);
90 utils.setPruning(false);
91 utils.setWeightContext("");
92 utils.setWeightType(Utils.GLOBAL_CHARACTER_WEIGHT);
93
94 SDDSaxParser sDDSaxParser = new SDDSaxParser(sddUri.toString(), utils);
95
96
97 DataSet data = sDDSaxParser.getDataset();
98
99 IdentificationKeyGenerator IkeyGenerator;
100 try {
101 IkeyGenerator = new IdentificationKeyGenerator(data, utils);
102 } catch (Exception e) {
103 logger.error("could not generate key", e);
104 throw new RuntimeException(e);
105 }
106 try {
107 IkeyGenerator.createIdentificationKey();
108 } catch (Exception e) {
109 //* IGNORE THIS TIME TO PREVENT FROM CREATING AN ERROR FILE */
110 }
111 SingleAccessKeyTree singleAccessKey = IkeyGenerator.getSingleAccessKeyTree();
112
113 // TODO idInSource for any cdm entity
114
115 cdmKey = PolytomousKey.NewTitledInstance(singleAccessKey.getLabel() + "_1");
116
117 featureVoc = TermVocabulary.NewInstance(TermType.Feature, singleAccessKey.getLabel(), singleAccessKey.getLabel(), null, null);
118
119 Set<PolytomousKeyNode> rootNode = recursivlyCreateKeyNodes(singleAccessKey.getRoot(), null);
120 // Assert.assertEquals(1, rootNode.size());
121 // cdmKey.setRoot(rootNode.iterator().next());
122
123 persistNewEntities();
124
125
126
127 return null;
128
129
130 }
131
132 private void persistNewEntities() {
133
134
135 // persist features
136 Collection features = featureMap.values();
137 getTermService().saveOrUpdate(features);
138 getVocabularyService().saveOrUpdate(featureVoc);
139
140 // persist the rest
141 getPolytomousKeyService().saveOrUpdate(cdmKey);
142 }
143
144 /**
145 * @param node
146 * @param parentNode may be null if node is the root node
147 * @return
148 */
149 private Set<PolytomousKeyNode> recursivlyCreateKeyNodes(SingleAccessKeyNode node, SingleAccessKeyNode parentNode) {
150
151 boolean isRootNode = (parentNode == null);
152
153
154 Set<PolytomousKeyNode> pkNodeSet = new HashSet<PolytomousKeyNode>();
155 if(node == null){
156 return pkNodeSet;
157 }
158
159 KeyStatement statement = getKeyStatementFrom(node);
160
161
162 //node.getNodeDescription(); // not needed here, contains warnings etc
163
164 // ---- do the children or taxa
165 List<SingleAccessKeyNode> childNodes = node.getChildren();
166 PolytomousKeyNode pkNode;
167 if(childNodes == null || childNodes.size() == 0 ){
168 // do the taxa
169 List<Taxon> taxa = node.getRemainingTaxa();
170 for(Taxon taxon : taxa){
171
172 pkNode = createPkNode(null, statement);
173
174 //TODO handle rank
175 NonViralName<?> nonViralName = NonViralName.NewInstance(Rank.UNKNOWN_RANK());
176 nonViralName.setTitleCache(taxon.getName(), true);
177 eu.etaxonomy.cdm.model.taxon.Taxon cdmTaxon = eu.etaxonomy.cdm.model.taxon.Taxon.NewInstance(
178 nonViralName, null); //FIXME !!!!!!
179 // TODO add taxon to covered taxa
180 // TODO media: get media from the parent node
181
182 pkNode.setTaxon(cdmTaxon);
183 pkNodeSet.add(pkNode);
184 }
185 } else {
186 // do the children
187 Feature feature = getFeatureFrom(childNodes.iterator().next().getCharacter());
188
189
190 pkNode = createPkNode(feature, statement);
191 for(SingleAccessKeyNode childNode : childNodes){
192
193 Set<PolytomousKeyNode> nodesToAdd = recursivlyCreateKeyNodes(childNode, node);
194 for(PolytomousKeyNode nodeToAdd : nodesToAdd){
195 pkNode.addChild(nodeToAdd);
196 }
197
198 }
199 pkNodeSet.add(pkNode);
200
201 if(isRootNode) {
202 cdmKey.setRoot(pkNode);
203 }
204 }
205
206
207 return pkNodeSet;
208 }
209
210 /**
211 * @param feature
212 * @param statement
213 * @return
214 */
215 public PolytomousKeyNode createPkNode(Feature feature, KeyStatement statement) {
216 PolytomousKeyNode pkNode;
217 pkNode = PolytomousKeyNode.NewInstance();
218 pkNode.setKey(cdmKey);
219 pkNode.setFeature(feature);
220 pkNode.setStatement(statement);
221 return pkNode;
222 }
223
224 /**
225 * @param node
226 * @return
227 */
228 public KeyStatement getKeyStatementFrom(SingleAccessKeyNode node) {
229 String label;
230 if(node.getCharacterState() instanceof QuantitativeMeasure){
231 label = ((QuantitativeMeasure) node.getCharacterState())
232 .toStringInterval(((QuantitativeCharacter) node.getCharacter())
233 .getMeasurementUnit());
234 } else {
235 label = node.getStringStates();
236 }
237 if (StringUtils.isBlank(label)){
238 return null;
239 }else{
240 return KeyStatement.NewInstance(label);
241 }
242 }
243
244 /**
245 * @param character
246 * @return
247 */
248 private Feature getFeatureFrom(ICharacter character) {
249
250
251 if(!featureMap.containsKey(character.getId())){
252
253 String featureLabel = character.getName();
254
255 Feature newFeature = Feature.NewInstance(featureLabel, featureLabel, null);
256 featureVoc.addTerm(newFeature);
257 featureMap.put(character.getId(),
258 newFeature);
259
260 }
261 return featureMap.get(character.getId());
262 }
263
264 @Override
265 protected void doInvoke(IkeyPlusImportState state) {
266 Utils utils = null;
267 try {
268 this.getKey(state.getConfig().getSource(), utils);
269 } catch (Exception e) {
270 e.printStackTrace();
271 }
272 }
273
274
275 @Override
276 protected boolean doCheck(IkeyPlusImportState state) {
277 // TODO Auto-generated method stub
278 return false;
279 }
280
281 @Override
282 protected boolean isIgnore(IkeyPlusImportState state) {
283 // TODO Auto-generated method stub
284 return false;
285 }
286
287 }