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