First draft of class for natural language generation functions.
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / NaturalLanguageGenerator.java
1 package eu.etaxonomy.cdm.api.service;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6 import java.util.Set;
7
8 import org.apache.xerces.dom.ElementImpl;
9 import org.apache.xerces.impl.xpath.regex.ParseException;
10 import org.springframework.stereotype.Component;
11
12 import eu.etaxonomy.cdm.model.common.CdmBase;
13 import eu.etaxonomy.cdm.model.common.VersionableEntity;
14 import eu.etaxonomy.cdm.model.description.CategoricalData;
15 import eu.etaxonomy.cdm.model.description.DescriptionBase;
16 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
17 import eu.etaxonomy.cdm.model.description.Feature;
18 import eu.etaxonomy.cdm.model.description.FeatureNode;
19 import eu.etaxonomy.cdm.model.description.FeatureTree;
20 import eu.etaxonomy.cdm.model.description.QuantitativeData;
21 import eu.etaxonomy.cdm.model.description.State;
22 import eu.etaxonomy.cdm.model.description.StateData;
23 import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
24 import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
25 import eu.etaxonomy.cdm.model.description.TaxonDescription;
26 import eu.etaxonomy.cdm.model.description.TextData;
27 import eu.etaxonomy.cdm.model.taxon.Taxon;
28 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
29 import eu.etaxonomy.cdm.model.common.Language;
30
31 @Component
32 public class NaturalLanguageGenerator implements INaturalLanguageGenerator {
33
34 public List<TextData> generateNaturalLanguageDescription(FeatureTree featureTree,Set<TaxonDescription> descriptions) {
35 return buildBranchesDescr(featureTree.getRootChildren(), featureTree.getRoot(), descriptions, false);
36 }
37
38 private List<TextData> buildBranchesDescr(List<FeatureNode> children, FeatureNode parent, Set<TaxonDescription> descriptions, boolean leaf) {
39 List<TextData> listTextData = new ArrayList<TextData>(); ;
40 if (!parent.isLeaf()){
41 Feature fref = parent.getFeature();
42 for (Iterator<FeatureNode> ifn = children.iterator() ; ifn.hasNext() ;){
43 FeatureNode fn = ifn.next();
44 listTextData.addAll(buildBranchesDescr(fn.getChildren(),fn,descriptions, leaf));
45 }
46 }
47 else {
48 Feature fref = parent.getFeature();
49 if (fref!=null) { // needs a better algorithm
50 for (Iterator<TaxonDescription> db = descriptions.iterator() ; db.hasNext() ;){
51 TaxonDescription descriptionBase = db.next();
52 Set<DescriptionElementBase> elements = descriptionBase.getElements();
53 for (Iterator<DescriptionElementBase> deb = elements.iterator() ; deb.hasNext() ;){
54 DescriptionElementBase descriptionElement = deb.next();
55 TextData textData = TextData.NewInstance();
56 if (descriptionElement.getFeature().getLabel().equals(fref.getLabel())){
57 if (descriptionElement instanceof CategoricalData) {
58 CategoricalData categoricalData = (CategoricalData) descriptionElement;
59 textData = buildCategoricalDescr(categoricalData);
60 listTextData.add(textData);
61 }
62 if (descriptionElement instanceof QuantitativeData) {
63 QuantitativeData quantitativeData = (QuantitativeData) descriptionElement;
64 textData = buildQuantitativeDescr(quantitativeData);
65 listTextData.add(textData);
66 }
67 }
68 }
69 }
70 leaf = true;
71 }
72 }
73 return listTextData;
74 }
75
76 //TODO manage different languages
77 private TextData buildQuantitativeDescr (QuantitativeData quantitativeData) throws ParseException {
78
79 boolean average = false;
80 float averagevalue = new Float(0);
81 boolean sd = false;
82 float sdvalue = new Float(0);
83 boolean min = false;
84 float minvalue = new Float(0);
85 boolean max = false;
86 float maxvalue = new Float(0);
87 boolean lowerb = false;
88 float lowerbvalue = new Float(0);
89 boolean upperb = false;
90 float upperbvalue = new Float(0);
91
92 StringBuilder QuantitativeDescription = new StringBuilder();
93 Feature feature = quantitativeData.getFeature();
94 TextData textData = TextData.NewInstance(feature);
95 QuantitativeDescription.append(" "+feature.getLabel());
96 String unit = quantitativeData.getUnit().getLabel();
97 Set<StatisticalMeasurementValue> statisticalValues = quantitativeData.getStatisticalValues();
98 for (Iterator<StatisticalMeasurementValue> smv = statisticalValues.iterator() ; smv.hasNext() ;){
99 StatisticalMeasurementValue statisticalValue = smv.next();
100 StatisticalMeasure type = statisticalValue.getType();
101 String label = type.getLabel();
102 if (label.equals("Average")) {
103 average = true;
104 averagevalue = statisticalValue.getValue();
105 } else if (label.equals("StandardDeviation")) {
106 sd = true;
107 sdvalue = statisticalValue.getValue();
108 } else if (label.equals("Min")) {
109 min = true;
110 minvalue = statisticalValue.getValue();
111 } else if (label.equals("Max")) {
112 max = true;
113 maxvalue = statisticalValue.getValue();
114 } else if (label.equals("TypicalLowerBoundary")) {
115 lowerb = true;
116 lowerbvalue = statisticalValue.getValue();
117 } else if (label.equals("TypicalUpperBoundary")) {
118 upperb = true;
119 upperbvalue = statisticalValue.getValue();
120 }
121 }
122 if (max && min) {
123 QuantitativeDescription.append(" from " + minvalue + " to " + maxvalue + unit);
124 }
125 else if (min) {
126 QuantitativeDescription.append(" from " + minvalue + " " + unit);
127 }
128 else if (max) {
129 QuantitativeDescription.append(" up to " + maxvalue + " " + unit);
130 }
131 if ((max||min)&&(lowerb||upperb)) {
132 QuantitativeDescription.append(",");
133 }
134 if ((lowerb||upperb)&&(min||max)) {
135 QuantitativeDescription.append(" most frequently");
136 }
137 if (upperb && lowerb) {
138 QuantitativeDescription.append(" from " + lowerbvalue + " to " + upperbvalue + unit);
139 }
140 else if (lowerb) {
141 QuantitativeDescription.append(" from " + lowerbvalue + " " + unit);
142 }
143 else if (upperb) {
144 QuantitativeDescription.append(" up to " + upperbvalue + " " + unit);
145 }
146 if (((max||min)&&(average))||((lowerb||upperb)&&(average))) {
147 QuantitativeDescription.append(",");
148 }
149 if (average) {
150 QuantitativeDescription.append(" " + averagevalue + unit + " on average ");
151 if (sd) {
152 QuantitativeDescription.append("(+/- " + sdvalue + ")");
153 }
154 }
155 textData.putText(QuantitativeDescription.toString(), Language.ENGLISH());
156 return textData;
157 }
158
159 private TextData buildCategoricalDescr(CategoricalData categoricalData) throws ParseException {
160 Feature feature = categoricalData.getFeature();
161 TextData textData = TextData.NewInstance(feature);
162 List<StateData> states = categoricalData.getStates();
163 StringBuilder CategoricalDescription = new StringBuilder();
164 CategoricalDescription.append(" "+feature.getLabel());
165 for (Iterator<StateData> sd = states.iterator() ; sd.hasNext() ;){
166 StateData stateData = sd.next();
167 State s = stateData.getState();
168 CategoricalDescription.append(" " + s.getLabel());
169 }
170 textData.putText(CategoricalDescription.toString(), Language.ENGLISH());
171 return textData ;
172 }
173
174 }