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