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