Project

General

Profile

Download (10.1 KB) Statistics
| Branch: | Tag: | Revision:
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
package eu.etaxonomy.taxeditor.ui.section;
10

    
11
import java.util.Collection;
12
import java.util.EnumSet;
13
import java.util.Observable;
14
import java.util.Observer;
15

    
16
import org.eclipse.jface.util.PropertyChangeEvent;
17
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.widgets.Composite;
19
import org.eclipse.swt.widgets.Display;
20

    
21
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
22
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
23
import eu.etaxonomy.cdm.common.CdmUtils;
24
import eu.etaxonomy.cdm.model.common.CdmBase;
25
import eu.etaxonomy.cdm.model.name.TaxonName;
26
import eu.etaxonomy.cdm.model.permission.CRUD;
27
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
28
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
29
import eu.etaxonomy.taxeditor.model.MessagingUtils;
30
import eu.etaxonomy.taxeditor.store.CdmStore;
31
import eu.etaxonomy.taxeditor.store.LoginManager;
32
import eu.etaxonomy.taxeditor.store.StoreUtil;
33
import eu.etaxonomy.taxeditor.ui.element.AbstractRelevanceFormElement;
34
import eu.etaxonomy.taxeditor.ui.element.CacheRelevance;
35
import eu.etaxonomy.taxeditor.ui.element.CacheRelevanceHelper;
36
import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
37
import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
38
import eu.etaxonomy.taxeditor.ui.element.ICacheRelevantFormElement;
39
import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
40
import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
41
import eu.etaxonomy.taxeditor.ui.element.LabelElement;
42
import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
43
import eu.etaxonomy.taxeditor.ui.element.ToggleableTextElement;
44

    
45
/**
46
 * @author n.hoffmann
47
 * @created Feb 26, 2010
48
 */
49
public abstract class AbstractCdmDetailElement<T>
50
		extends AbstractRelevanceFormElement
51
		implements ICdmDetailElement<T>, Observer{
52

    
53
	private T entity;
54

    
55
	protected boolean enabled = true;
56

    
57
	private LabelElement warnForReferencedObjects;
58

    
59
	protected EnumSet<CRUD> requiredCrud = null;
60

    
61
	public AbstractCdmDetailElement(CdmFormFactory formFactory,
62
			ICdmFormElement formElement) {
63
		super(formFactory, formElement);
64
		// register as property change listener
65
		formFactory.addPropertyChangeListener(this);
66
		CdmStore.getLoginManager().addObserver(this);
67

    
68
		getLayoutComposite().getParent().addDisposeListener(
69
		        e -> CdmStore.getLoginManager().deleteObserver(AbstractCdmDetailElement.this));
70
	}
71

    
72
	/**
73
	 * Sets the entity and updates controls
74
	 */
75
	@Override
76
    public void setEntity(T entity) {
77
        this.entity = entity;
78
        // the id is always 0 if the entity was not yet saved, so it is new in this case
79
        if(getEntity() == null || (getEntity() instanceof CdmBase && StoreUtil.getCdmEntity(getEntity()).getId() == 0)) {
80
            // new entity, not yet saved
81
            requiredCrud = EnumSet.of(CRUD.CREATE);
82
        } else {
83
            requiredCrud = EnumSet.of(CRUD.UPDATE);
84
        }
85
        updateContent();
86
	}
87

    
88
	public void setEntityWithoutUpdate(T entity){
89
	    this.entity = entity;
90
        // the id is always 0 if the entity was not yet saved, so it is new in this case
91
        if(getEntity() == null || (getEntity() instanceof CdmBase && StoreUtil.getCdmEntity(getEntity()).getId() == 0)) {
92
            // new entity, not yet saved
93
            requiredCrud = EnumSet.of(CRUD.CREATE);
94
        } else {
95
            requiredCrud = EnumSet.of(CRUD.UPDATE);
96
        }
97
	}
98

    
99
	@Override
100
    public T getEntity() {
101
		return entity;
102
	}
103

    
104
	/**
105
	 * Updates all widgets to display the latest data
106
	 */
107
	protected void updateContent() {
108
		removeElements();
109
		createControls(this, entity, SWT.NONE);
110
		updateControlStates();
111
	}
112

    
113
    @Override
114
    public void setSelected(boolean selected) {
115
		Composite section = getLayoutComposite().getParent();
116
		section.setBackground(selected ? SELECTED : getPersistentBackground());
117
	}
118

    
119
	/**
120
	 * Sets all field to the given enablement state except the objects in
121
	 * the collection except parameter.
122
	 *
123
	 * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#setEnabled(boolean)
124
	 */
125
	public void setEnabled(boolean enabled, Collection<Object> except) {
126
	    this.enabled = enabled;
127
		for (ICdmFormElement element : getElements()) {
128
			if (element instanceof IEnableableFormElement) {
129
				IEnableableFormElement enableableElement = (IEnableableFormElement) element;
130
				if (except != null && except.contains(enableableElement)) {
131
					// enableableElement.setEnabled(enabled);
132
				} else {
133
					enableableElement.setEnabled(enabled);
134
				}
135
			}
136
		}
137
	}
138

    
139
	@Override
140
	public boolean isEnabled() {
141
	    return enabled;
142
	}
143

    
144
    @Override
145
    public void setEnabled(boolean enabled) {
146
        setEnabled(enabled, null);
147
    }
148

    
149
    @Override
150
    public CacheRelevance cacheRelevance() {
151
        return cacheRelevanceHelper.cacheRelevance();
152
    }
153

    
154
    @Override
155
    public void addDependsOnCache(ToggleableTextElement toggleElement) {
156
        cacheRelevanceHelper.addDependsOnCache(toggleElement);
157
    }
158

    
159
    protected void registerCacheRelevance(ICacheRelevantFormElement element, ToggleableTextElement... toggleableCaches) {
160
        if (element != null && toggleableCaches != null) {
161
             for (ToggleableTextElement toggleableCache : toggleableCaches){
162
                 if (toggleableCache != null){
163
                     element.addDependsOnCache(toggleableCache);
164
                 }
165
             }
166
        }
167
//        updateCacheRelevance();
168
    }
169

    
170
	/**
171
	 * Updates the cache relevance state of all internal elements of this
172
	 * AbstractCdmDetailElement.
173
	 */
174
	@Override
175
    public void updateCacheRelevance(){
176
	    CacheRelevanceHelper.updateCacheRelevanceForSubelements(getElements());
177
	}
178

    
179
	/**
180
	 * Create all content elements
181
	 */
182
	protected abstract void createControls(ICdmFormElement formElement,
183
			T entity, int style);
184

    
185
	@Override
186
	public void propertyChange(PropertyChangeEvent event) {
187
		if (event == null) {
188
			return;
189
		}
190

    
191
		handleTitleCacheRelevantChange(event);
192

    
193
		Object eventSource = event.getSource();
194

    
195
		if (eventSource instanceof ICdmFormElement) {
196
			ICdmFormElement eventElement = (ICdmFormElement) eventSource;
197
			ICdmFormElement eventElementContainer = eventElement.getParentElement();
198
			if (eventElementContainer == this) {
199
				if (event instanceof CdmPropertyChangeEvent) {
200
					if (((CdmPropertyChangeEvent) event).hasException()) {
201
						handleException((CdmPropertyChangeEvent) event);
202
						return;
203
					}
204
				}
205
				// call specific handler implementation
206
				handleEvent(eventSource);
207
				// refire the event
208
				firePropertyChangeEvent(this, event);
209
				// update possible parents
210
				updateParentSection();
211
			}
212
		}
213
	}
214

    
215
	protected void handleTitleCacheRelevantChange(PropertyChangeEvent event) {
216
		boolean isRelevant = getEntity() instanceof TaxonName
217
				|| getEntity() instanceof TaxonBase;
218
		isRelevant &= this instanceof AbstractIdentifiableEntityDetailElement;
219

    
220
		if (isRelevant) {
221
			((AbstractIdentifiableEntityDetailElement<?>)this).updateToggleableCacheField();
222
		}
223
	}
224

    
225
	private void updateParentSection() {
226
		if (getParentElement() instanceof AbstractCdmDetailSection) {
227
			((AbstractCdmDetailSection<?>) getParentElement()).updateTitle();
228
		}
229
		//NOTE: This slows down the rendering of the details view
230
//		StoreUtil.reflowParentScrolledForm(getLayoutComposite(), true);
231
	}
232

    
233
	/**
234
	 * Gets called when the source of the event is a child widget of this
235
	 * widget.
236
	 */
237
	public abstract void handleEvent(Object eventSource);
238

    
239
	public void handleException(CdmPropertyChangeEvent event) {
240
		// override this in subclasses if you want to deal with the error
241
		MessagingUtils.error(event.getSource().getClass(), event.getException());
242
	}
243

    
244
	@Override
245
    public ConversationHolder getConversationHolder() {
246
		if (getParentElement() instanceof IConversationEnabled) {
247
			return ((IConversationEnabled) getParentElement())
248
					.getConversationHolder();
249
		}
250
		throw new IllegalArgumentException(
251
				"Parent element should be IConversationEnabled");
252
	}
253

    
254
	@Override
255
    public void update(CdmDataChangeMap changeEvents) {
256
	}
257

    
258
	@Override
259
    public void update(Observable o, Object arg){
260
        if(o instanceof LoginManager){
261
            updateControlStates();
262
        }
263
    }
264

    
265
    protected void updateControlStates(){
266
        if (getEntity() != null && getEntity() instanceof CdmBase){
267
            enabled = enabled && CdmStore.currentAuthentiationHasPermission(StoreUtil.getCdmEntity(getEntity()), requiredCrud);
268
        }else{
269
            enabled = true;
270
        }
271
        setEnabled(enabled);
272
    }
273

    
274
	public LabelElement getWarnForReferencedObjects() {
275
		return warnForReferencedObjects;
276
	}
277

    
278
	public void setWarnForReferencedObjects(LabelElement warnForReferencedObjects) {
279
		this.warnForReferencedObjects = warnForReferencedObjects;
280
	}
281

    
282
	public void setWarnForReferencingObjects(ICdmFormElement formElement, int defaultReferencingObjects){
283
	    if (getEntity() instanceof CdmBase){
284
	    	CdmBase cdmBase = (CdmBase) getEntity();
285
	    	if (cdmBase.getId() != 0){
286
		        long referencingObjectsCount = CdmStore.getCommonService().getReferencingObjectsCount(cdmBase);
287

    
288
	    		if (referencingObjectsCount > defaultReferencingObjects){
289
	    			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")));
290
	    			getWarnForReferencedObjects().setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
291
	    			getWarnForReferencedObjects().setLayout(LayoutConstants.FILL(2, 3));
292
	    			getWarnForReferencedObjects().setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
293
	    			formFactory.createLabel(formElement, "");
294
	    		}
295
	    	}
296
	    }
297
	}
298

    
299
	public void setWarnForReferencingObjects(ICdmFormElement formElement){
300
	    setWarnForReferencingObjects(formElement, 1);
301
	}
302

    
303
	public void setWarnForReferencingObjectsVisible(boolean isVisible){
304
		if (getWarnForReferencedObjects() != null){
305
			getWarnForReferencedObjects().setVisible(isVisible);
306
		}
307
	}
308
}
(1-1/9)