merge-update from trunk
[cdmlib.git] / cdmlib-remote / src / main / java / eu / etaxonomy / cdm / remote / vaadin / components / DemoTaxonTable.java
1 package eu.etaxonomy.cdm.remote.vaadin.components;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.HashMap;
6 import java.util.HashSet;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Set;
10 import java.util.UUID;
11
12 import javax.annotation.PostConstruct;
13
14 import org.apache.log4j.Logger;
15 import org.springframework.beans.factory.annotation.Autowired;
16 import org.springframework.context.annotation.Scope;
17 import org.springframework.stereotype.Component;
18
19 import com.vaadin.annotations.PreserveOnRefresh;
20 import com.vaadin.data.util.BeanItemContainer;
21 import com.vaadin.server.VaadinSession;
22 import com.vaadin.ui.ComboBox;
23 import com.vaadin.ui.Label;
24 import com.vaadin.ui.Notification;
25 import com.vaadin.ui.Table;
26
27 import eu.etaxonomy.cdm.api.service.IClassificationService;
28 import eu.etaxonomy.cdm.api.service.IDescriptionService;
29 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
30 import eu.etaxonomy.cdm.api.service.ITaxonService;
31 import eu.etaxonomy.cdm.api.service.ITermService;
32 import eu.etaxonomy.cdm.api.service.IVocabularyService;
33 import eu.etaxonomy.cdm.model.common.CdmBase;
34 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
35 import eu.etaxonomy.cdm.model.common.TermVocabulary;
36 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
37 import eu.etaxonomy.cdm.model.description.Distribution;
38 import eu.etaxonomy.cdm.model.description.Feature;
39 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;
40 import eu.etaxonomy.cdm.model.description.TaxonDescription;
41 import eu.etaxonomy.cdm.model.location.NamedArea;
42 import eu.etaxonomy.cdm.model.taxon.Taxon;
43 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
44 import eu.etaxonomy.cdm.remote.dto.vaadin.CdmTaxonTableCollection;
45 import eu.etaxonomy.cdm.remote.vaadin.data.LazyLoadedContainer;
46
47 /**
48 *
49 * This class is a Vaadin Component. It starts a long running session at the moment.
50 * This might change in the future, but for now it beautifully works for this prototype.<p>
51 * This class takes advantage of the dto and fills a container with data from the DB. Lazyloading or
52 * Paging needs to be used!!!!
53 * <p>
54 * Further clarification is needed about the exact process when marking this component as dirty.
55 * What will happen to the bound session? Why are changed Object saved without calling services explicitly.
56 *
57 *
58 * @author a.oppermann
59 *
60 */
61
62 @Component
63 @Scope("request")
64 @PreserveOnRefresh
65 public class DemoTaxonTable extends Table{
66
67 /**
68 * automatic generated ID
69 */
70 @Autowired
71 IVocabularyService vocabularyService;
72 @Autowired
73 ITaxonService taxonService;
74 @Autowired
75 IDescriptionService descriptionService;
76 @Autowired
77 ITermService termService;
78 @Autowired
79 IClassificationService clService;
80 @Autowired
81 ITaxonNodeService taxonNodeService;
82 @Autowired
83 IClassificationService classificationService;
84
85 Logger logger = Logger.getLogger(DemoTaxonTable.class);
86
87
88 private static final long serialVersionUID = 1L;
89
90 @PostConstruct
91 @SuppressWarnings("rawtypes")
92 void PostConstruct(){
93
94 // final BeanItemContainer<CdmTaxonTableCollection> redListContainer = new BeanItemContainer<CdmTaxonTableCollection>(CdmTaxonTableCollection.class);
95 //TODO: Make use of paging
96 // VaadinSession session = VaadinSession.getCurrent();
97 // UUID uuid = UUID.fromString(session.getAttribute("classificationUUID").toString());
98 // Classification classification = clService.load(uuid);
99 // List<TaxonNode> listAllNodes = taxonNodeService.listAllNodesForClassification(classification, null, null);
100
101 // Collection<Taxon> listTaxon = taxonService.list(Taxon.class, null, null, null, NODE_INIT_STRATEGY);
102 // for(TaxonNode taxonNode:listAllNodes){
103 //
104 // Taxon taxon = taxonNode.getTaxon();
105 // List<PresenceAbsenceTermBase> termList = termService.list(PresenceAbsenceTermBase.class, null, null, null, DESCRIPTION_INIT_STRATEGY);
106 // List<DescriptionElementBase> listTaxonDescription = descriptionService.listDescriptionElementsForTaxon(taxon, null, null, null, null, DESCRIPTION_INIT_STRATEGY);
107 // CdmTaxonTableCollection tableCollection = new CdmTaxonTableCollection(taxon, listTaxonDescription, termList);
108 // redListContainer.addBean(tableCollection);
109 // }
110
111 VaadinSession session = VaadinSession.getCurrent();
112 UUID termUUID = (UUID) session.getAttribute("selectedTerm");
113 TermVocabulary<DefinedTermBase> term = vocabularyService.load(termUUID);
114 term = CdmBase.deproxy(term, TermVocabulary.class);
115 Set<DefinedTermBase> terms = term.getTerms();
116
117 final LazyLoadedContainer container = new LazyLoadedContainer(CdmTaxonTableCollection.class, classificationService, taxonNodeService);
118
119 // container.addContainerProperty("fullTitleCache", String.class, null);
120 // container.addContainerProperty("rank", String.class, null);
121
122 //String[] columns = ; //,"distributionStatus"
123 ArrayList<String> columnList = new ArrayList<String>(Arrays.asList(new String[]{"fullTitleCache","rank"}));
124 ArrayList<String> headerList = new ArrayList<String>(Arrays.asList(new String[]{"Taxon","Rang"}));
125 for(final DefinedTermBase dt : terms){
126 columnList.add(dt.getTitleCache());
127 headerList.add(dt.getTitleCache());
128 // container.addContainerProperty(dt.getTitleCache(), String.class, null);
129
130 addContainerProperty(dt.getTitleCache(), String.class, null);
131 try{
132 addGeneratedColumn(dt.getTitleCache(), new ColumnGenerator() {
133 public Object generateCell(Table source, Object itemId, Object columnId) {
134 Label tf = new Label();
135 ComboBox box = null;
136 if(itemId instanceof TaxonNode){
137 TaxonNode tn = CdmBase.deproxy((TaxonNode) itemId, TaxonNode.class);
138 Taxon taxon = CdmBase.deproxy(tn.getTaxon(), Taxon.class);
139 taxon =(Taxon) taxonService.load(taxon.getUuid());
140 HashMap<DescriptionElementBase, Distribution> map = getDistribution(taxon);
141
142 List<PresenceAbsenceTermBase> listTerm = termService.list(PresenceAbsenceTermBase.class, null, null, null, DESCRIPTION_INIT_STRATEGY);
143 BeanItemContainer<PresenceAbsenceTermBase> termContainer = new BeanItemContainer<PresenceAbsenceTermBase>(PresenceAbsenceTermBase.class);
144 termContainer.addAll(listTerm);
145 box = new ComboBox("Occurrence Status: ", termContainer);
146 box.setImmediate(true);
147
148 if(map != null){
149 /** update field **/
150 DescriptionElementBase deb = null;
151 Distribution db = null;
152 for(Map.Entry<DescriptionElementBase, Distribution> entry : map.entrySet()){
153 deb = entry.getKey();
154 db = entry.getValue();
155 }
156 if(isEditable()){
157 box = updateDistributionField(deb, db, termContainer, box, taxon);
158 }else{
159 if(db.getStatus() != null){
160 tf.setValue(db.getStatus().toString());
161 }else{
162 //FIXME: case for delete?
163 Notification.show("Possible Error for " +taxon.getTitleCache() + " for Distribution: " + db.getArea().getTitleCache(), Notification.Type.TRAY_NOTIFICATION);
164 tf.setValue("-");
165 }
166 }
167 }else{
168 /** create distribution if it does not exist and set the status **/
169 if(isEditable()){
170 box = createDistributionField(taxon, termContainer, box);
171 }else{
172 tf.setValue("-");
173 }
174 }
175
176 }
177
178 if(isEditable()){
179 return box;
180 }else{
181 return tf;
182 }
183 }
184
185 private ComboBox createDistributionField(
186 final Taxon taxon,
187 BeanItemContainer<PresenceAbsenceTermBase> termContainer,ComboBox box) {
188 final ComboBox box2 = box;
189 box.addValueChangeListener(new ValueChangeListener() {
190
191 @Override
192 public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
193 NamedArea area = (NamedArea) dt;
194 Distribution db = Distribution.NewInstance(area, (PresenceAbsenceTermBase<?>) box2.getValue());
195 Set<TaxonDescription> descriptions = taxon.getDescriptions();
196 if (descriptions != null) {
197 for (TaxonDescription desc : descriptions) {
198 // add to first taxon description
199 desc.addElement(db);
200 descriptionService.saveOrUpdate(desc);
201 break;
202 }
203 } else {// there are no TaxonDescription yet.
204 TaxonDescription td = TaxonDescription.NewInstance(taxon);
205 td.addElement(db);
206 taxon.addDescription(td);
207 taxonService.saveOrUpdate(taxon);
208 }
209 }
210
211 });
212
213
214 return box;
215 }
216
217 private HashMap<DescriptionElementBase, Distribution> getDistribution(Taxon taxon){
218 Set<Feature> setFeature = new HashSet<Feature>(Arrays.asList(Feature.DISTRIBUTION()));
219 List<DescriptionElementBase> listTaxonDescription = descriptionService.listDescriptionElementsForTaxon(taxon, setFeature, null, null, null, DESCRIPTION_INIT_STRATEGY);
220 for(DescriptionElementBase deb : listTaxonDescription){
221 if(deb instanceof Distribution){
222 Distribution db = (Distribution)deb;
223 String titleCache = dt.getTitleCache();
224 if(db.getArea().getTitleCache().equalsIgnoreCase(titleCache)){
225 HashMap<DescriptionElementBase, Distribution> map = new HashMap<DescriptionElementBase, Distribution>();
226 map.put(deb, db);
227 return map;
228 }
229 }
230 }
231 return null;
232 }
233
234 private ComboBox updateDistributionField(DescriptionElementBase deb, Distribution db, BeanItemContainer<PresenceAbsenceTermBase> termContainer, ComboBox box, Taxon taxon) {
235 final Distribution db2 = db;
236 final DescriptionElementBase deb2 = deb;
237 box.setValue(db.getStatus());
238 final ComboBox box2 = box;
239 final Taxon taxon2 = taxon;
240 box.addValueChangeListener(new ValueChangeListener() {
241
242 private static final long serialVersionUID = 1L;
243
244 @Override
245 public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
246 if(box2.getValue() == null){//delete descriptionElementBase
247 descriptionService.deleteDescriptionElement(deb2);
248 taxonService.saveOrUpdate(taxon2);
249 Notification.show("Delete Status", Notification.Type.TRAY_NOTIFICATION);
250 }else{
251 db2.setStatus((PresenceAbsenceTermBase)box2.getValue());
252 descriptionService.saveDescriptionElement(deb2);
253 Notification.show("DescriptionService wrote", Notification.Type.TRAY_NOTIFICATION);
254 }
255 }
256 });
257 return box;
258 }
259 });
260 }catch(IllegalArgumentException e){
261 e.printStackTrace();
262 }
263 }
264
265 setContainerDataSource(container);
266 setColumnReorderingAllowed(true);
267 setSortEnabled(false);
268 // setVisibleColumns(columns);
269 Object[] visibleColumns = columnList.toArray();
270 setVisibleColumns(visibleColumns);
271 setColumnHeaders(headerList.toArray(new String[headerList.size()]));//new String[]{"Taxon", "Rang"});// ,"Deutschland"
272 setColumnCollapsingAllowed(true);
273 setSelectable(true);
274 setSizeUndefined();
275 setSizeFull();
276 setPageLength(20);
277 setFooterVisible(true);
278 setColumnFooter("fullTitleCache", "Total amount of Taxa displayed: " + container.size());
279
280 setCacheRate(10);
281 }
282
283 private static final List<String> NODE_INIT_STRATEGY = Arrays.asList(new String[]{
284 "descriptions",
285 "descriptions.*",
286 "description.state",
287 "feature",
288 "feature.*",
289 "childNodes",
290 "childNodes.taxon",
291 "childNodes.taxon.name",
292 "taxonNodes",
293 "taxonNodes.*",
294 "taxonNodes.taxon.*",
295 "taxon.*",
296 "taxon.descriptions",
297 "taxon.sec",
298 "taxon.name.*",
299 "taxon.synonymRelations",
300 "terms",
301 "name.*",
302 "name.rank.representations",
303 "name.status.type.representations",
304 "sources.$",
305 "stateData.$"
306 });
307
308 protected static final List<String> DESCRIPTION_INIT_STRATEGY = Arrays.asList(new String []{
309 "$",
310 "elements.*",
311 "elements.sources.citation.authorship.$",
312 "elements.sources.nameUsedInSource.originalNameString",
313 "elements.area.level",
314 "elements.modifyingText",
315 "elements.states.*",
316 "elements.media",
317 "elements.multilanguageText",
318 "multilanguageText",
319 "stateData.$"
320 });
321 }