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