added check for entity being null
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / section / AbstractCdmDetailElement.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.ui.section;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.EnumSet;
16 import java.util.Observable;
17 import java.util.Observer;
18
19 import org.eclipse.jface.util.PropertyChangeEvent;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.events.DisposeEvent;
22 import org.eclipse.swt.events.DisposeListener;
23 import org.eclipse.swt.widgets.Composite;
24
25 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
26 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
27 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
28 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
29 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
30 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
31 import eu.etaxonomy.taxeditor.model.MessagingUtils;
32 import eu.etaxonomy.taxeditor.store.CdmStore;
33 import eu.etaxonomy.taxeditor.store.LoginManager;
34 import eu.etaxonomy.taxeditor.store.StoreUtil;
35 import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
36 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
37 import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
38 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
39 import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
40
41 /**
42 * <p>
43 * Abstract AbstractCdmDetailElement class.
44 * </p>
45 *
46 * @author n.hoffmann
47 * @created Feb 26, 2010
48 * @version 1.0
49 */
50 public abstract class AbstractCdmDetailElement<T> extends AbstractCdmFormElement implements ICdmDetailElement<T>, Observer {
51
52 private T entity;
53
54 private boolean irrelevant;
55
56 private boolean enabled;
57
58 private EnumSet<CRUD> requiredCrud = null;
59
60 /**
61 * <p>
62 * Constructor for AbstractCdmDetailElement.
63 * </p>
64 *
65 * @param formFactory
66 * a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory}
67 * object.
68 * @param formElement
69 * a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
70 * object.
71 * @param <T>
72 * a T object.
73 */
74 public AbstractCdmDetailElement(CdmFormFactory formFactory,
75 ICdmFormElement formElement) {
76 super(formFactory, formElement);
77 // register as property change listener
78 formFactory.addPropertyChangeListener(this);
79 CdmStore.getLoginManager().addObserver(this);
80
81 getLayoutComposite().getParent().addDisposeListener(new DisposeListener() {
82
83 @Override
84 public void widgetDisposed(DisposeEvent e) {
85 CdmStore.getLoginManager().deleteObserver(AbstractCdmDetailElement.this);
86 }
87 });
88 }
89
90 /**
91 * Sets the entity and updates controls
92 *
93 * @param entity
94 * a T object.
95 */
96 @Override
97 public void setEntity(T entity) {
98 this.entity = entity;
99 // the id is always 0 if the entity was not yet saved, so it is new in this case
100 if(getEntity() == null || StoreUtil.getCdmEntity(getEntity()).getId() == 0) {
101 // new entity, not yet saved
102 requiredCrud = EnumSet.of(CRUD.CREATE);
103 } else {
104 requiredCrud = EnumSet.of(CRUD.UPDATE);
105 }
106 updateContent();
107 }
108
109 /*
110 * (non-Javadoc)
111 *
112 * @see eu.etaxonomy.taxeditor.forms.IEntityElement#getEntity()
113 */
114 /**
115 * <p>
116 * Getter for the field <code>entity</code>.
117 * </p>
118 *
119 * @return a T object.
120 */
121 @Override
122 public T getEntity() {
123 return entity;
124 }
125
126 /**
127 * Updates all widgets to display the latest data
128 */
129 protected void updateContent() {
130 removeElements();
131 createControls(this, entity, SWT.WRAP);
132 getLayoutComposite().layout();
133
134 updateControlStates();
135 }
136
137 /*
138 * (non-Javadoc)
139 *
140 * @see
141 * eu.etaxonomy.taxeditor.forms.ISelectableComposite#setSelected(boolean)
142 */
143 /** {@inheritDoc} */
144 @Override
145 public void setSelected(boolean selected) {
146 Composite section = getLayoutComposite().getParent();
147 section.setBackground(selected ? SELECTED : getPersistentBackground());
148 }
149
150 /**
151 * Sets all field to the given enablement state except the objects in
152 * collection except
153 *
154 * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#setEnabled(boolean)
155 * @param enabled
156 * a boolean.
157 * @param except
158 * a {@link java.util.Collection} object.
159 */
160 public void setEnabled(boolean enabled, Collection<Object> except) {
161 this.enabled = enabled;
162 for (ICdmFormElement element : getElements()) {
163 if (element instanceof IEnableableFormElement) {
164 IEnableableFormElement enableableElement = (IEnableableFormElement) element;
165 if (except != null && except.contains(enableableElement)) {
166 // enableableElement.setEnabled(enabled);
167 } else {
168 enableableElement.setEnabled(enabled);
169 }
170 }
171 }
172 }
173
174 /* (non-Javadoc)
175 * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#isEnabled()
176 */
177 @Override
178 public boolean isEnabled() {
179 return enabled;
180 }
181
182 /**
183 * <p>
184 * Setter for the field <code>irrelevant</code>.
185 * </p>
186 *
187 * @param irrelevant
188 * a boolean.
189 * @param except
190 * a {@link java.util.Collection} object.
191 */
192 public void setIrrelevant(boolean irrelevant, Collection<Object> except) {
193 // logger.warn("Setting " + this.getClass().getSimpleName() +
194 // " to irrelevant state: " + irrelevant);
195 for (ICdmFormElement element : getElements()) {
196 if (element instanceof IEnableableFormElement) {
197 IEnableableFormElement relevantElement = (IEnableableFormElement) element;
198 if (except != null && except.contains(relevantElement)) {
199 // do nothing
200 // logger.warn("not setting elements irrelevance: " +
201 // relevantElement.getClass().getSimpleName() + " in :" +
202 // this.getClass().getSimpleName());
203 } else {
204 relevantElement.setIrrelevant(irrelevant);
205 }
206 }
207 }
208 }
209
210 /** {@inheritDoc} */
211 @Override
212 public void setEnabled(boolean enabled) {
213 setEnabled(enabled, null);
214 }
215
216 /** {@inheritDoc} */
217 @Override
218 public void setIrrelevant(boolean irrelevant) {
219 this.irrelevant = irrelevant;
220 setIrrelevant(irrelevant, null);
221 }
222
223 /**
224 * Create all content elements
225 *
226 * @param formElement
227 * a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
228 * object.
229 * @param entity
230 * a T object.
231 * @param style
232 * a int.
233 */
234 protected abstract void createControls(ICdmFormElement formElement,
235 T entity, int style);
236
237 /** {@inheritDoc} */
238 @Override
239 public void propertyChange(PropertyChangeEvent event) {
240 if (event == null) {
241 return;
242 }
243
244 handleTitleCacheRelevantChange(event);
245
246 Object eventSource = event.getSource();
247
248 if (eventSource instanceof ICdmFormElement) {
249 ICdmFormElement eventElement = (ICdmFormElement) eventSource;
250 ICdmFormElement eventElementContainer = eventElement
251 .getParentElement();
252
253 if (eventElementContainer == this) {
254 if (event instanceof CdmPropertyChangeEvent) {
255 if (((CdmPropertyChangeEvent) event).hasException()) {
256 handleException((CdmPropertyChangeEvent) event);
257 return;
258 }
259 }
260 // call specific handler implementation
261 handleEvent(eventSource);
262 // refire the event
263 firePropertyChangeEvent(this, event);
264 // update possible parents
265 updateParentSection();
266 }
267 }
268 }
269
270 protected void handleTitleCacheRelevantChange(PropertyChangeEvent event) {
271 boolean isRelevant = getEntity() instanceof TaxonNameBase
272 || getEntity() instanceof TaxonBase;
273 isRelevant &= this instanceof AbstractIdentifiableEntityDetailElement;
274
275 if (isRelevant) {
276 ((AbstractIdentifiableEntityDetailElement) this)
277 .updateToggleableCacheField();
278 updateParentSection();
279 }
280 }
281
282 private void updateParentSection() {
283 if (getParentElement() instanceof AbstractCdmDetailSection) {
284 ((AbstractCdmDetailSection) getParentElement()).updateTitle();
285 }
286 }
287
288 /**
289 * Gets called when the source of the event is a child widget of this
290 * widget.
291 *
292 * @param eventSource
293 * a {@link java.lang.Object} object.
294 */
295 public abstract void handleEvent(Object eventSource);
296
297 /**
298 * <p>
299 * handleException
300 * </p>
301 *
302 * @param event
303 * a
304 * {@link eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent}
305 * object.
306 */
307 public void handleException(CdmPropertyChangeEvent event) {
308 // override this in subclasses if you want to deal with the error
309 MessagingUtils.error(event.getSource().getClass(), event.getException());
310 }
311
312 /**
313 * <p>
314 * isIrrelevant
315 * </p>
316 *
317 * @return a boolean.
318 */
319 public boolean isIrrelevant() {
320 return irrelevant;
321 }
322
323 /**
324 * <p>
325 * getConversationHolder
326 * </p>
327 *
328 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
329 * object.
330 */
331 @Override
332 public ConversationHolder getConversationHolder() {
333 if (getParentElement() instanceof IConversationEnabled) {
334 return ((IConversationEnabled) getParentElement())
335 .getConversationHolder();
336 }
337 throw new IllegalArgumentException(
338 "Parent element should be IConversationEnabled");
339 }
340
341 /** {@inheritDoc} */
342 @Override
343 public void update(CdmDataChangeMap changeEvents) {
344 }
345
346 @Override
347 public void update(Observable o, Object arg){
348 if(o instanceof LoginManager){
349 updateControlStates();
350 }
351 }
352
353
354 protected void updateControlStates(){
355 Collection<Object> except = new ArrayList<Object>();
356 for(ICdmFormElement formElement:getElements()){
357 if(formElement instanceof IEnableableFormElement && !((IEnableableFormElement) formElement).isEnabled()){
358 except.add(formElement);
359 }
360 }
361 setEnabled(getEntity() != null && CdmStore.currentAuthentiationHasPermission(StoreUtil.getCdmEntity(getEntity()), requiredCrud), except);
362 }
363 }