ref #7439 Remove sort type combo box
[taxeditor.git] / eu.etaxonomy.taxeditor.bulkeditor / src / main / java / eu / etaxonomy / taxeditor / bulkeditor / input / AbstractBulkEditorInput.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 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
23 import ca.odell.glazedlists.BasicEventList;
24 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
25 import eu.etaxonomy.cdm.api.service.config.DeleteConfiguratorBase;
26 import eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator;
27 import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableException;
28 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
29 import eu.etaxonomy.cdm.model.common.CdmBase;
30 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
31 import eu.etaxonomy.cdm.model.common.MarkerType;
32 import eu.etaxonomy.cdm.strategy.merge.IMergable;
33 import eu.etaxonomy.cdm.strategy.merge.MergeException;
34 import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityCreator;
35 import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityPersistenceService;
36 import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorQuery;
37 import eu.etaxonomy.taxeditor.bulkeditor.IBulkEditorSortProvider;
38 import eu.etaxonomy.taxeditor.bulkeditor.input.sortprovider.CdmBaseSortProvider;
39 import eu.etaxonomy.taxeditor.bulkeditor.internal.TaxeditorBulkeditorPlugin;
40 import eu.etaxonomy.taxeditor.editor.CdmEntitySessionInput;
41 import eu.etaxonomy.taxeditor.l10n.Messages;
42 import eu.etaxonomy.taxeditor.model.MessagingUtils;
43 import eu.etaxonomy.taxeditor.store.CdmStore;
44
45 /**
46 * @author p.ciardelli
47 * @created 25.06.2009
48 * @version 1.0
49 * @param <T>
50 */
51 public abstract class AbstractBulkEditorInput<T extends CdmBase> extends CdmEntitySessionInput implements
52 IEntityPersistenceService<T> {
53
54 private UUID entityUuid;
55
56 private BasicEventList<T> model = new BasicEventList<>();
57
58 private Map<T, DeleteConfiguratorBase> toDelete = new HashMap<>();
59 private List<T> saveCandidates = new ArrayList<>();
60
61
62 private Set<T> markedMergeCandidates = new HashSet<>();
63 private T markedMergeTarget = null;
64
65 private HashMap<T, Set<T>> mergedEntities = new HashMap<>();
66
67 private IEntityCreator<T> entityCreator;
68 private final ConversationHolder conversation;
69
70 private Job searchJob;
71
72 public AbstractBulkEditorInput() {
73 super(true);
74 this.conversation = CdmStore.createConversation();
75 }
76
77 static public AbstractBulkEditorInput NewInstance(BulkEditorInputType inputType) {
78
79 return BulkEditorInputType.getInput(inputType);
80 }
81
82 public static AbstractBulkEditorInput NewInstance(IdentifiableEntity entity) {
83
84 BulkEditorInputType inputType = BulkEditorInputType.getByType(entity.getClass());
85
86 AbstractBulkEditorInput editorInput = NewInstance(inputType);
87
88 editorInput.setEntityUuid(entity.getUuid());
89
90 return editorInput;
91 }
92
93 public abstract String getName();
94
95 public String getEditorName(){
96 return getName();
97 }
98
99 protected int getPageSize(){
100 return 100;
101 }
102
103 protected abstract List<T> listEntities(IIdentifiableEntityServiceConfigurator configurator);
104
105 protected abstract long countEntities(IIdentifiableEntityServiceConfigurator configurator);
106
107 protected abstract T loadEntity(UUID entityUuid);
108
109 public void setMergeTarget(T t){
110 markedMergeTarget = t;
111 }
112
113 public Set<T> getMergeCandidates() {
114 return markedMergeCandidates;
115 }
116
117 public T getMergeTarget() {
118 return markedMergeTarget;
119 }
120
121 public void removeMergeTarget(){
122 markedMergeTarget = null;
123 }
124
125 public void addMergeCandidate(T t){
126 markedMergeCandidates.add(t);
127 }
128
129 public void removeMergeCandidate(T t){
130 markedMergeCandidates.remove(t);
131 }
132
133 public void addToDelete(T t, DeleteConfiguratorBase config) {
134 toDelete.put(t, config);
135 }
136 public void addSaveCandidate(T t){
137 saveCandidates.add(t);
138 }
139 private void setEntityUuid(UUID entityUuid){
140 this.entityUuid = entityUuid;
141 }
142
143 public UUID getEntityUuid() {
144 return entityUuid;
145 }
146
147 public void performSearch(final BulkEditorQuery bulkEditorQuery) {
148 //cancel previous search job
149 if(searchJob!=null && searchJob.getState()!=Job.NONE){
150 searchJob.cancel();
151 searchJob = null;
152 }
153 model.clear();
154
155 if(getEntityUuid() != null){
156
157 T entity = loadEntity(getEntityUuid());
158 model.add(entity);
159 }
160 else if(bulkEditorQuery != null){
161
162 IIdentifiableEntityServiceConfigurator configurator = bulkEditorQuery.getSearchConfigurator();
163
164 int pageSize = configurator.getPageSize()!=null?configurator.getPageSize():getPageSize();
165 long count = countEntities(configurator);
166 int totalWork = count>Integer.MAX_VALUE?Integer.MAX_VALUE:(int)count;
167 String jobLabel = String.format(Messages.AbstractBulkEditorInput_LOADING, getName(), bulkEditorQuery.getSearchString());
168 searchJob = Job.create(jobLabel, (ICoreRunnable) monitor -> {
169 monitor.beginTask(jobLabel, totalWork);
170 int pageNumber = 0;
171 List<T> entities;
172 do {
173 if (monitor.isCanceled()) {
174 break;
175 }
176 configurator.setPageNumber(pageNumber);
177 entities = listEntities(configurator);
178 model.addAll(entities);
179 pageNumber++;
180 monitor.worked(pageSize);
181 long workedLong = pageSize*pageNumber;
182 int loadedCount = workedLong>Integer.MAX_VALUE?Integer.MAX_VALUE:(int)workedLong;
183 monitor.setTaskName(String.format(Messages.AbstractBulkEditorInput_LOADED, loadedCount, totalWork, getName()));
184 } while (!entities.isEmpty());
185 monitor.done();
186 });
187 searchJob.setUser(true);
188 searchJob.schedule();
189 }
190 }
191
192 public boolean isMergingEnabled() {
193 return false;
194 }
195
196 public boolean isConvertingEnabled() {
197 return false;
198 }
199
200 public boolean isMarkerTypeEditingEnabled(MarkerType markerType) {
201 return false;
202 }
203
204
205 /** {@inheritDoc} */
206 @Override
207 public boolean merge(T entity, T mergeTarget) {
208 if (entity instanceof IMergable) {
209 try {
210 CdmStore.getCommonService().merge(mergeTarget.getUuid(), entity.getUuid(), (Class<? extends CdmBase>)entity.getClass());
211 } catch (MergeException e) {
212 MessagingUtils.errorDialog(Messages.AbstractBulkEditorInput_MERGE_ERROR_TITLE,
213 this,
214 String.format(Messages.AbstractBulkEditorInput_MERGE_ERROR_MESSAGE, entity.getClass().getName()),
215 TaxeditorBulkeditorPlugin.PLUGIN_ID,
216 e,
217 true);
218 }
219 }
220 return true;
221 }
222
223 public void saveModel(){
224 saveModel(true);
225 }
226
227 public void saveModel(boolean resetMerge){
228 //delete entities
229 for(Entry<T, DeleteConfiguratorBase> entry:toDelete.entrySet()){
230 try {
231 delete(entry.getKey(), entry.getValue());
232 } catch (ReferencedObjectUndeletableException e) {
233 e.printStackTrace();
234 }
235 }
236 toDelete.clear();
237 if (!saveCandidates.isEmpty()){
238 CdmStore.getService(saveCandidates.get(0)).merge(saveCandidates, true);
239 }
240 if(resetMerge){
241 //merge entities
242 for(T mergeTarget:mergedEntities.keySet()){
243 for (T mergeCandidate: mergedEntities.get(mergeTarget)){
244 merge(mergeCandidate, mergeTarget);
245 }
246 }
247 mergedEntities.clear();
248
249 }
250 }
251
252
253 /** {@inheritDoc} */
254 @Override
255 public T create(T entity) {
256 return save(entity);
257 }
258
259 public IEntityCreator<T> getEntityCreator(){
260 if(entityCreator == null){
261 entityCreator = createEntityCreator();
262 }
263 return entityCreator;
264 }
265
266 protected abstract IEntityCreator<T> createEntityCreator();
267
268 /**
269 * The default implementation returns an empty list of sort providers.
270 * @return
271 */
272 public List<IBulkEditorSortProvider<T>> getSortProviders(){
273 List<IBulkEditorSortProvider<T>> sortProviders = new ArrayList<IBulkEditorSortProvider<T>>();
274
275 sortProviders.add(new CdmBaseSortProvider<T>());
276
277 return sortProviders;
278 }
279
280 /**
281 * Returns a textual representation given object. The default implementation
282 * in the abstract base class returns the simple name of the class, this may
283 * be overwritten to something more specific in subclasses.
284 *
285 * @param entity
286 * @return a textual representation given object.
287 */
288 public String getTypeText(Object entity){
289 return entity.getClass().getSimpleName();
290 }
291
292 public String getText(T entity) {
293 if(entity instanceof IdentifiableEntity){
294 IdentifiableEntity identifiableEntity = (IdentifiableEntity) HibernateProxyHelper.deproxy(entity);
295 String text = ""; //$NON-NLS-1$
296 if(markedMergeCandidates.contains(entity)){
297 text += Messages.AbstractBulkEditorInput_CANDIDATE;
298 }
299 else if(markedMergeTarget==entity){
300 text += Messages.AbstractBulkEditorInput_TARGET;
301 }
302 text += identifiableEntity.getTitleCache();
303 return text;
304 }
305
306 return "No text. Implement in subclass"; //$NON-NLS-1$
307 }
308
309 public BasicEventList<T> getModel() {
310 return model;
311 }
312
313 protected boolean replaceInModel(T entity) {
314 int index = model.indexOf(entity);
315 if(index >= 0) {
316 model.set(index, entity);
317 return true;
318 } else {
319 return false;
320 }
321 }
322
323 @Override
324 public List<T> getRootEntities() {
325 return getModel();
326 }
327
328
329 @Override
330 public Map<Object, List<String>> getPropertyPathsMap() {
331 // TODO Auto-generated method stub
332 return null;
333 }
334
335 public ConversationHolder getConversation() {
336 return conversation;
337 }
338
339 public List<T> getSaveCandidates() {
340 return saveCandidates;
341 }
342
343 /**
344 *
345 */
346 public void resetSaveCandidates() {
347 this.saveCandidates.clear();
348
349 }
350
351 public HashMap<T, Set<T>> getMergedEntities() {
352 return mergedEntities;
353 }
354
355 public void setMergedEntities(HashMap<T, Set<T>> mergedEntities) {
356 this.mergedEntities = mergedEntities;
357 }
358 }