Project

General

Profile

Download (10.8 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.Comparator;
13
import java.util.HashMap;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Map.Entry;
18
import java.util.Set;
19
import java.util.UUID;
20

    
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.input.sortprovider.TitleCacheComparator;
41
import eu.etaxonomy.taxeditor.bulkeditor.internal.TaxeditorBulkeditorPlugin;
42
import eu.etaxonomy.taxeditor.editor.CdmEntitySessionInput;
43
import eu.etaxonomy.taxeditor.event.EventUtility;
44
import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
45
import eu.etaxonomy.taxeditor.l10n.Messages;
46
import eu.etaxonomy.taxeditor.model.MessagingUtils;
47
import eu.etaxonomy.taxeditor.store.CdmStore;
48

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

    
58
	private UUID entityUuid;
59

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

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

    
65

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

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

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

    
74
    private Job searchJob;
75

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

    
81
	static public AbstractBulkEditorInput NewInstance(BulkEditorInputType inputType) {
82

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

    
86
	public static AbstractBulkEditorInput NewInstance(IdentifiableEntity entity) {
87

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

    
90
		AbstractBulkEditorInput editorInput = NewInstance(inputType);
91

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

    
94
		return editorInput;
95
	}
96

    
97
    public abstract String getName();
98

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

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

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

    
109
	protected abstract long countEntities(IIdentifiableEntityServiceConfigurator configurator);
110

    
111
	protected abstract T loadEntity(UUID entityUuid);
112

    
113
	public Comparator<T> getTitleComparator(){
114
	    return new TitleCacheComparator();
115
	}
116

    
117
	public void setMergeTarget(T t){
118
	    markedMergeTarget = t;
119
	}
120

    
121
    public Set<T> getMergeCandidates() {
122
        return markedMergeCandidates;
123
    }
124

    
125
    public T getMergeTarget() {
126
        return markedMergeTarget;
127
    }
128

    
129
	public void removeMergeTarget(){
130
	    markedMergeTarget = null;
131
	}
132

    
133
	public void addMergeCandidate(T t){
134
	    markedMergeCandidates.add(t);
135
	}
136

    
137
	public void removeMergeCandidate(T t){
138
		markedMergeCandidates.remove(t);
139
	}
140

    
141
    public void addToDelete(T t, DeleteConfiguratorBase config) {
142
        toDelete.put(t, config);
143
    }
144
    public void addSaveCandidate(T t){
145
        saveCandidates.add(t);
146
    }
147
	private void setEntityUuid(UUID entityUuid){
148
		this.entityUuid = entityUuid;
149
	}
150

    
151
	public UUID getEntityUuid() {
152
		return entityUuid;
153
	}
154

    
155
	public void performSearch(final BulkEditorQuery bulkEditorQuery, IStructuredSelection selection) {
156
	    //cancel previous search job
157
	    if(searchJob!=null && searchJob.getState()!=Job.NONE){
158
	        searchJob.cancel();
159
	        searchJob = null;
160
	    }
161
	    model.clear();
162

    
163
		if(getEntityUuid() != null){
164

    
165
			T entity = loadEntity(getEntityUuid());
166
			model.add(entity);
167
		}
168
		else if(bulkEditorQuery != null){
169

    
170
			IIdentifiableEntityServiceConfigurator configurator = bulkEditorQuery.getSearchConfigurator();
171

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

    
204
	public boolean isMergingEnabled() {
205
		return false;
206
	}
207

    
208
	public boolean isConvertingEnabled() {
209
		return false;
210
	}
211

    
212
	public boolean isMarkerTypeEditingEnabled(MarkerType markerType) {
213
		return false;
214
	}
215

    
216

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

    
235
	public void saveModel(){
236
	    saveModel(true);
237
	}
238

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

    
264

    
265
	/** {@inheritDoc} */
266
	@Override
267
    public T create(T entity) {
268
		return save(entity);
269
	}
270

    
271
	public IEntityCreator<T> getEntityCreator(){
272
		if(entityCreator == null){
273
			entityCreator = createEntityCreator();
274
		}
275
		return entityCreator;
276
	}
277

    
278
	protected abstract IEntityCreator<T> createEntityCreator();
279

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

    
287
		sortProviders.add(new CdmBaseSortProvider<T>());
288

    
289
		return sortProviders;
290
	}
291

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

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

    
318
		return "No text. Implement in subclass"; //$NON-NLS-1$
319
	}
320

    
321
	public BasicEventList<T> getModel() {
322
		return model;
323
	}
324

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

    
335
    @Override
336
    public List<T> getRootEntities() {
337
        return getModel();
338
    }
339

    
340

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

    
347
	public ConversationHolder getConversation() {
348
		return conversation;
349
	}
350

    
351
	public Set<T> getSaveCandidates() {
352
        return saveCandidates;
353
    }
354

    
355
    public HashMap<T, Set<T>> getMergedEntities() {
356
        return mergedEntities;
357
    }
358

    
359
    public void setMergedEntities(HashMap<T, Set<T>> mergedEntities) {
360
        this.mergedEntities = mergedEntities;
361
    }
362
}
(1-1/11)