Merge branch 'hotfix/4.5.1'
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / view / descriptive / DescriptiveContentProvider.java
1 /**
2 *
3 */
4 package eu.etaxonomy.taxeditor.editor.view.descriptive;
5
6 import java.util.ArrayList;
7 import java.util.Collections;
8 import java.util.Comparator;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Set;
12
13 import org.eclipse.jface.viewers.ITreeContentProvider;
14 import org.eclipse.jface.viewers.Viewer;
15
16 import eu.etaxonomy.cdm.model.common.Marker;
17 import eu.etaxonomy.cdm.model.description.DescriptionBase;
18 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
19 import eu.etaxonomy.cdm.model.description.Feature;
20 import eu.etaxonomy.cdm.model.description.FeatureTree;
21 import eu.etaxonomy.cdm.model.description.IDescribable;
22 import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
23 import eu.etaxonomy.taxeditor.editor.definedterm.input.TermEditorInput;
24 import eu.etaxonomy.taxeditor.model.FeatureNodeContainer;
25 import eu.etaxonomy.taxeditor.model.FeatureNodeContainerTree;
26 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
27 import eu.etaxonomy.taxeditor.store.TermStore;
28 import eu.etaxonomy.taxeditor.store.UsageTermCollection;
29
30 /**
31 * <p>DescriptiveContentProvider class.</p>
32 *
33 * @author p.ciardelli
34 * @author n.hoffmann
35 * @version $Id: $
36 */
37 public class DescriptiveContentProvider implements ITreeContentProvider {
38
39 protected static final Object[] NO_CHILDREN = new Object[0];
40 protected Map<DescriptionBase<?>, FeatureNodeContainerTree> featureNodeContainerCache;
41 private boolean showOnlyIndividualAssociations;
42
43
44 public DescriptiveContentProvider(Map<DescriptionBase<?>, FeatureNodeContainerTree> featureNodeContainerCache) {
45 this(featureNodeContainerCache, false);
46 }
47 /**
48 * <p>Constructor for DescriptiveContentProvider.</p>
49 *
50 * @param featureNodeContainerCache a {@link java.util.Map} object.
51 */
52 public DescriptiveContentProvider(Map<DescriptionBase<?>, FeatureNodeContainerTree> featureNodeContainerCache, boolean showOnlyIndividualAssociations) {
53 this.featureNodeContainerCache = featureNodeContainerCache;
54 this.showOnlyIndividualAssociations = showOnlyIndividualAssociations;
55 }
56
57 /* (non-Javadoc)
58 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
59 */
60 /** {@inheritDoc} */
61 @Override
62 public Object[] getChildren(Object parentElement) {
63 if (parentElement instanceof IDescribable<?>) {
64 return getDescriptions((IDescribable<?>) parentElement).toArray();
65 }
66 else if (parentElement instanceof DescriptionBase<?>) {
67 if ( ! ((DescriptionBase<?>) parentElement).isImageGallery()) {
68 DescriptionBase<?> description = (DescriptionBase<?>) parentElement;
69
70 FeatureNodeContainerTree containerTree = getContainerTreeForDesription(description);
71 List<FeatureNodeContainer> children = containerTree.getRoot().getChildren();
72 //filter out containers with no children
73 List<FeatureNodeContainer> childrenWithChildren = new ArrayList<FeatureNodeContainer>();
74 for (FeatureNodeContainer featureNodeContainer : children) {
75 if(getChildren(featureNodeContainer).length>0){
76 childrenWithChildren.add(featureNodeContainer);
77 }
78 }
79 return childrenWithChildren.toArray();
80 }
81 }
82 else if (parentElement instanceof FeatureNodeContainer){
83 FeatureNodeContainer container = (FeatureNodeContainer) parentElement;
84 if(container.isLeaf()){
85 List<DescriptionElementBase> descriptionElements = container.getDescriptionElements();
86 List<IndividualsAssociation> individualAssociations = new ArrayList<IndividualsAssociation>();
87 for (DescriptionElementBase descriptionElement : descriptionElements) {
88 if(descriptionElement instanceof IndividualsAssociation){
89 individualAssociations.add((IndividualsAssociation) descriptionElement);
90 }
91 }
92 //sort individual associations by title cache of associated specimens
93 Collections.sort(individualAssociations, new Comparator<IndividualsAssociation>() {
94
95 @Override
96 public int compare(IndividualsAssociation o1, IndividualsAssociation o2) {
97 if(o1==null || o1.getAssociatedSpecimenOrObservation()==null){
98 return -1;
99 }
100 if(o2==null || o2.getAssociatedSpecimenOrObservation()==null){
101 return 1;
102 }
103 return o1.getAssociatedSpecimenOrObservation().compareTo(o2.getAssociatedSpecimenOrObservation());
104 }
105 });
106 if(showOnlyIndividualAssociations){
107 descriptionElements = new ArrayList<DescriptionElementBase>(individualAssociations);
108 }
109 return descriptionElements.toArray();
110 }else{
111 return container.getChildren().toArray();
112 }
113 }
114
115 return NO_CHILDREN;
116 }
117
118 private FeatureNodeContainerTree getContainerTreeForDesription(DescriptionBase<?> description){
119 if(! featureNodeContainerCache.containsKey(description)){
120 FeatureNodeContainerTree containerTree = new FeatureNodeContainerTree(description, getFeatureTree(description));
121 featureNodeContainerCache.put(description, containerTree);
122 }
123 return featureNodeContainerCache.get(description);
124 }
125
126 /** {@inheritDoc} */
127 @Override
128 public boolean hasChildren(Object element) {
129 if (element instanceof DescriptionBase<?>){
130 DescriptionBase<?> description = (DescriptionBase<?>) element;
131 FeatureNodeContainerTree containerTree = featureNodeContainerCache.get(description);
132 if(containerTree != null && containerTree.getRoot() != null){
133 return containerTree.getRoot().getChildren().size() != 0;
134 }
135 }
136 return getChildren(element).length != 0;
137 }
138
139 /**
140 * Retrieves the feature tree associated with the given description
141 *
142 * TODO as of now this is always the same thing because feature trees may not be associated
143 * to descriptions yet.
144 *
145 * @param description
146 * @return
147 */
148 private FeatureTree getFeatureTree(DescriptionBase description){
149
150 FeatureTree featureTree;
151 // TODO change this to the feature tree associated with this taxon description
152 if (description.hasStructuredData()){
153 featureTree = PreferencesUtil.getDefaultFeatureTreeForStructuredDescription();
154 }else{
155 featureTree = PreferencesUtil.getDefaultFeatureTreeForTextualDescription();
156 }
157
158 // create a transient tree with all features if none was selected
159 if(featureTree == null){
160 featureTree = TermEditorInput.getDefaultFeatureTree();
161 }
162
163 return featureTree;
164 }
165
166 /**
167 * Get all descriptions associated with the given object
168 * @param parentElement
169 * @return
170 */
171 protected List<DescriptionBase<?>> getDescriptions(IDescribable<?> parentElement) {
172 Set<? extends DescriptionBase<?>> elementDescriptions = parentElement.getDescriptions();
173 List<DescriptionBase<?>> resultDescriptions = new ArrayList<DescriptionBase<?>>();
174 for(DescriptionBase<?> description : elementDescriptions){
175 if(! description.isImageGallery()){
176 Set<Marker> descriptionMarkers = description.getMarkers();
177 if(descriptionMarkers != null && !descriptionMarkers.isEmpty()) {
178 for (Marker marker: descriptionMarkers) {
179 if(marker.getMarkerType() != null && !(marker.getMarkerType().getUuid().equals(UsageTermCollection.uuidUseMarkerType))) {
180 resultDescriptions.add(description);
181 }
182 }
183 }
184 else {
185 resultDescriptions.add(description);
186 }
187 }
188 }
189 return resultDescriptions;
190 }
191
192 /** {@inheritDoc} */
193 @Override
194 public Object getParent(Object element) {
195 return null;
196 }
197
198 /** {@inheritDoc} */
199 @Override
200 public Object[] getElements(Object inputElement) {
201 return getChildren(inputElement);
202 }
203
204 /**
205 * <p>dispose</p>
206 */
207 @Override
208 public void dispose() {
209 featureNodeContainerCache.clear();
210 }
211
212 /** {@inheritDoc} */
213 @Override
214 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
215
216 public void toggleShowOnlyIndividualAssociations() {
217 showOnlyIndividualAssociations = !showOnlyIndividualAssociations;
218 }
219
220 }