Project

General

Profile

Download (10.6 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.bulkeditor.input;
10

    
11
import java.util.ArrayList;
12
import java.util.HashMap;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.Map.Entry;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import org.eclipse.core.runtime.ICoreRunnable;
21
import org.eclipse.core.runtime.jobs.Job;
22
import org.eclipse.jface.viewers.IStructuredSelection;
23

    
24
import ca.odell.glazedlists.BasicEventList;
25
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
26
import eu.etaxonomy.cdm.api.service.config.DeleteConfiguratorBase;
27
import eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator;
28
import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableException;
29
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
30
import eu.etaxonomy.cdm.model.common.CdmBase;
31
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
32
import eu.etaxonomy.cdm.model.common.MarkerType;
33
import eu.etaxonomy.cdm.strategy.merge.IMergable;
34
import eu.etaxonomy.cdm.strategy.merge.MergeException;
35
import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityCreator;
36
import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityPersistenceService;
37
import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorQuery;
38
import eu.etaxonomy.taxeditor.bulkeditor.IBulkEditorSortProvider;
39
import eu.etaxonomy.taxeditor.bulkeditor.input.sortprovider.CdmBaseSortProvider;
40
import eu.etaxonomy.taxeditor.bulkeditor.internal.TaxeditorBulkeditorPlugin;
41
import eu.etaxonomy.taxeditor.editor.CdmEntitySessionInput;
42
import eu.etaxonomy.taxeditor.event.EventUtility;
43
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
44
import eu.etaxonomy.taxeditor.l10n.Messages;
45
import eu.etaxonomy.taxeditor.model.MessagingUtils;
46
import eu.etaxonomy.taxeditor.store.CdmStore;
47

    
48
/**
49
 * @author p.ciardelli
50
 * @created 25.06.2009
51
 * @version 1.0
52
 * @param <T>
53
 */
54
public abstract class AbstractBulkEditorInput<T extends CdmBase> extends CdmEntitySessionInput implements
55
    IEntityPersistenceService<T> {
56

    
57
	private UUID entityUuid;
58

    
59
	private BasicEventList<T> model = new BasicEventList<>();
60

    
61
	private Map<T, DeleteConfiguratorBase> toDelete = new HashMap<>();
62
	private Set<T> saveCandidates = new HashSet<>();
63

    
64

    
65
	private Set<T> markedMergeCandidates = new HashSet<>();
66
	private T markedMergeTarget = null;
67

    
68
	private HashMap<T, Set<T>> mergedEntities = new HashMap<>();
69

    
70
	private IEntityCreator<T> entityCreator;
71
	private final ConversationHolder conversation;
72

    
73
    private Job searchJob;
74

    
75
	public AbstractBulkEditorInput() {
76
	    super(true);
77
	    this.conversation = CdmStore.createConversation();
78
	}
79

    
80
	static public AbstractBulkEditorInput NewInstance(BulkEditorInputType inputType) {
81

    
82
		return BulkEditorInputType.getInput(inputType);
83
	}
84

    
85
	public static AbstractBulkEditorInput NewInstance(IdentifiableEntity entity) {
86

    
87
		BulkEditorInputType inputType = BulkEditorInputType.getByType(entity.getClass());
88

    
89
		AbstractBulkEditorInput editorInput = NewInstance(inputType);
90

    
91
		editorInput.setEntityUuid(entity.getUuid());
92

    
93
		return editorInput;
94
	}
95

    
96
    public abstract String getName();
97

    
98
    public String getEditorName(){
99
        return getName();
100
    }
101

    
102
    protected int getPageSize(){
103
        return 100;
104
    }
105

    
106
	protected abstract List<T> listEntities(IIdentifiableEntityServiceConfigurator configurator);
107

    
108
	protected abstract long countEntities(IIdentifiableEntityServiceConfigurator configurator);
109

    
110
	protected abstract T loadEntity(UUID entityUuid);
111

    
112
	public void setMergeTarget(T t){
113
	    markedMergeTarget = t;
114
	}
115

    
116
    public Set<T> getMergeCandidates() {
117
        return markedMergeCandidates;
118
    }
119

    
120
    public T getMergeTarget() {
121
        return markedMergeTarget;
122
    }
123

    
124
	public void removeMergeTarget(){
125
	    markedMergeTarget = null;
126
	}
127

    
128
	public void addMergeCandidate(T t){
129
	    markedMergeCandidates.add(t);
130
	}
131

    
132
	public void removeMergeCandidate(T t){
133
		markedMergeCandidates.remove(t);
134
	}
135

    
136
    public void addToDelete(T t, DeleteConfiguratorBase config) {
137
        toDelete.put(t, config);
138
    }
139
    public void addSaveCandidate(T t){
140
        saveCandidates.add(t);
141
    }
142
	private void setEntityUuid(UUID entityUuid){
143
		this.entityUuid = entityUuid;
144
	}
145

    
146
	public UUID getEntityUuid() {
147
		return entityUuid;
148
	}
149

    
150
	public void performSearch(final BulkEditorQuery bulkEditorQuery, IStructuredSelection selection) {
151
	    //cancel previous search job
152
	    if(searchJob!=null && searchJob.getState()!=Job.NONE){
153
	        searchJob.cancel();
154
	        searchJob = null;
155
	    }
156
	    model.clear();
157

    
158
		if(getEntityUuid() != null){
159

    
160
			T entity = loadEntity(getEntityUuid());
161
			model.add(entity);
162
		}
163
		else if(bulkEditorQuery != null){
164

    
165
			IIdentifiableEntityServiceConfigurator configurator = bulkEditorQuery.getSearchConfigurator();
166

    
167
            int pageSize = configurator.getPageSize()!=null?configurator.getPageSize():getPageSize();
168
			long count = countEntities(configurator);
169
			int totalWork = count>Integer.MAX_VALUE?Integer.MAX_VALUE:(int)count;
170
			String jobLabel = String.format(Messages.AbstractBulkEditorInput_LOADING, getName(), bulkEditorQuery.getSearchString());
171
	        searchJob = Job.create(jobLabel, (ICoreRunnable) monitor -> {
172
	            monitor.beginTask(jobLabel, totalWork);
173
	            int pageNumber = 0;
174
	            List<T> entities;
175
                do {
176
                    if (monitor.isCanceled()) {
177
                        break;
178
                    }
179
                    configurator.setPageNumber(pageNumber);
180
                    entities = listEntities(configurator);
181
                    model.addAll(entities);
182
                    //select if entity is loaded
183
                    if(selection!=null && model.containsAll(selection.toList())){
184
                        EventUtility.postAsyncEvent(WorkbenchEventConstants.BULK_EDITOR_SEARCH_FINISHED, selection);
185
                    }
186
                    pageNumber++;
187
                    monitor.worked(pageSize);
188
                    long workedLong = pageSize*pageNumber;
189
                    int loadedCount =  workedLong>Integer.MAX_VALUE?Integer.MAX_VALUE:(int)workedLong;
190
                    monitor.setTaskName(String.format(Messages.AbstractBulkEditorInput_LOADED, loadedCount, totalWork, getName()));
191
                } while (!entities.isEmpty());
192
	            monitor.done();
193
	            if(selection!=null){
194
	                EventUtility.postAsyncEvent(WorkbenchEventConstants.BULK_EDITOR_SEARCH_FINISHED, selection);
195
	            }
196
	        });
197
	        searchJob.schedule();
198
		}
199
	}
200

    
201
	public boolean isMergingEnabled() {
202
		return false;
203
	}
204

    
205
	public boolean isConvertingEnabled() {
206
		return false;
207
	}
208

    
209
	public boolean isMarkerTypeEditingEnabled(MarkerType markerType) {
210
		return false;
211
	}
212

    
213

    
214
	/** {@inheritDoc} */
215
	@Override
216
    public boolean merge(T entity, T mergeTarget) {
217
		if (entity instanceof IMergable) {
218
			try {
219
				CdmStore.getCommonService().merge(mergeTarget.getUuid(), entity.getUuid(), (Class<? extends CdmBase>)entity.getClass());
220
			} catch (MergeException e) {
221
				MessagingUtils.errorDialog(Messages.AbstractBulkEditorInput_MERGE_ERROR_TITLE,
222
						this,
223
						String.format(Messages.AbstractBulkEditorInput_MERGE_ERROR_MESSAGE, entity.getClass().getName()),
224
						TaxeditorBulkeditorPlugin.PLUGIN_ID,
225
						e,
226
						true);
227
			}
228
		}
229
		return true;
230
	}
231

    
232
	public void saveModel(){
233
	    saveModel(true);
234
	}
235

    
236
	public void saveModel(boolean resetMerge){
237
	    //delete entities
238
	    for(Entry<T, DeleteConfiguratorBase> entry:toDelete.entrySet()){
239
	        try {
240
                delete(entry.getKey(), entry.getValue());
241
            } catch (ReferencedObjectUndeletableException e) {
242
                e.printStackTrace();
243
            }
244
	    }
245
	    if (!saveCandidates.isEmpty()){
246
	        CdmStore.getService(saveCandidates.iterator().next()).merge(new ArrayList<>(saveCandidates), true);
247
        }
248
	    if(resetMerge){
249
	        //merge entities
250
	        for(T mergeTarget:mergedEntities.keySet()){
251
	            for (T mergeCandidate: mergedEntities.get(mergeTarget)){
252
	                merge(mergeCandidate, mergeTarget);
253
	            }
254
	        }
255
	    }
256
	    toDelete.clear();
257
	    saveCandidates.clear();
258
	    mergedEntities.clear();
259
	}
260

    
261

    
262
	/** {@inheritDoc} */
263
	@Override
264
    public T create(T entity) {
265
		return save(entity);
266
	}
267

    
268
	public IEntityCreator<T> getEntityCreator(){
269
		if(entityCreator == null){
270
			entityCreator = createEntityCreator();
271
		}
272
		return entityCreator;
273
	}
274

    
275
	protected abstract IEntityCreator<T> createEntityCreator();
276

    
277
	/**
278
	 * The default implementation returns an empty list of sort providers.
279
	 * @return
280
	 */
281
	public List<IBulkEditorSortProvider<T>> getSortProviders(){
282
		List<IBulkEditorSortProvider<T>> sortProviders = new ArrayList<IBulkEditorSortProvider<T>>();
283

    
284
		sortProviders.add(new CdmBaseSortProvider<T>());
285

    
286
		return sortProviders;
287
	}
288

    
289
	/**
290
	 * Returns a textual representation given object. The default implementation
291
	 * in the abstract base class returns the simple name of the class, this may
292
	 * be overwritten to something more specific in subclasses.
293
	 *
294
	 * @param entity
295
	 * @return a textual representation given object.
296
	 */
297
	public String getTypeText(Object entity){
298
		return entity.getClass().getSimpleName();
299
	}
300

    
301
	public String getText(T entity) {
302
		if(entity instanceof IdentifiableEntity){
303
			IdentifiableEntity identifiableEntity = (IdentifiableEntity) HibernateProxyHelper.deproxy(entity);
304
			String text = ""; //$NON-NLS-1$
305
			if(markedMergeCandidates.contains(entity)){
306
			    text += Messages.AbstractBulkEditorInput_CANDIDATE;
307
			}
308
			else if(markedMergeTarget==entity){
309
			    text += Messages.AbstractBulkEditorInput_TARGET;
310
			}
311
			text += identifiableEntity.getTitleCache();
312
			return text;
313
		}
314

    
315
		return "No text. Implement in subclass"; //$NON-NLS-1$
316
	}
317

    
318
	public BasicEventList<T> getModel() {
319
		return model;
320
	}
321

    
322
	public boolean replaceInModel(T entity) {
323
	    int index = model.indexOf(entity);
324
	    if(index >= 0) {
325
	        model.set(index, entity);
326
	        return true;
327
	    } else {
328
	        return false;
329
	    }
330
	}
331

    
332
    @Override
333
    public List<T> getRootEntities() {
334
        return getModel();
335
    }
336

    
337

    
338
    @Override
339
    public Map<Object, List<String>> getPropertyPathsMap() {
340
        // TODO Auto-generated method stub
341
        return null;
342
    }
343

    
344
	public ConversationHolder getConversation() {
345
		return conversation;
346
	}
347

    
348
	public Set<T> getSaveCandidates() {
349
        return saveCandidates;
350
    }
351

    
352
    public HashMap<T, Set<T>> getMergedEntities() {
353
        return mergedEntities;
354
    }
355

    
356
    public void setMergedEntities(HashMap<T, Set<T>> mergedEntities) {
357
        this.mergedEntities = mergedEntities;
358
    }
359
}
(1-1/11)