ref #6321 Fix search service invocation for users and groups
[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.Collections;
13 import java.util.Comparator;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Map.Entry;
19 import java.util.Set;
20 import java.util.UUID;
21
22 import org.eclipse.core.runtime.ICoreRunnable;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.jobs.Job;
25
26 import ca.odell.glazedlists.BasicEventList;
27 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
28 import eu.etaxonomy.cdm.api.service.config.DeleteConfiguratorBase;
29 import eu.etaxonomy.cdm.api.service.config.IIdentifiableEntityServiceConfigurator;
30 import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableException;
31 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
32 import eu.etaxonomy.cdm.model.common.CdmBase;
33 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
34 import eu.etaxonomy.cdm.model.common.MarkerType;
35 import eu.etaxonomy.cdm.strategy.merge.IMergable;
36 import eu.etaxonomy.cdm.strategy.merge.MergeException;
37 import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityCreator;
38 import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityPersistenceService;
39 import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorQuery;
40 import eu.etaxonomy.taxeditor.bulkeditor.IBulkEditorSortProvider;
41 import eu.etaxonomy.taxeditor.bulkeditor.input.sortprovider.CdmBaseSortProvider;
42 import eu.etaxonomy.taxeditor.bulkeditor.input.sortprovider.TitleCacheComparator;
43 import eu.etaxonomy.taxeditor.bulkeditor.internal.TaxeditorBulkeditorPlugin;
44 import eu.etaxonomy.taxeditor.editor.CdmEntitySessionInput;
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 List<T> saveCandidates = new ArrayList<>();
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 abstract List<T> listEntities(IIdentifiableEntityServiceConfigurator configurator);
104
105 protected abstract T loadEntity(UUID entityUuid);
106
107 public void setMergeTarget(T t){
108 markedMergeTarget = t;
109 }
110
111 public Set<T> getMergeCandidates() {
112 return markedMergeCandidates;
113 }
114
115 public T getMergeTarget() {
116 return markedMergeTarget;
117 }
118
119 public void removeMergeTarget(){
120 markedMergeTarget = null;
121 }
122
123 public void addMergeCandidate(T t){
124 markedMergeCandidates.add(t);
125 }
126
127 public void removeMergeCandidate(T t){
128 markedMergeCandidates.remove(t);
129 }
130
131 public void addToDelete(T t, DeleteConfiguratorBase config) {
132 toDelete.put(t, config);
133 }
134 public void addSaveCandidate(T t){
135 saveCandidates.add(t);
136 }
137 private void setEntityUuid(UUID entityUuid){
138 this.entityUuid = entityUuid;
139 }
140
141 public UUID getEntityUuid() {
142 return entityUuid;
143 }
144
145 public void performSearch(final BulkEditorQuery bulkEditorQuery) {
146 if(searchJob!=null && searchJob.getState()!=Job.NONE){
147 MessagingUtils.informationDialog(Messages.AbstractBulkEditorInput_MULTIPLE_SEARCH_TITLE, Messages.AbstractBulkEditorInput_MULTIPLE_SEARCH_MESSAGE);
148 return;
149 }
150 model.clear();
151
152 if(getEntityUuid() != null){
153
154 T entity = loadEntity(getEntityUuid());
155 model.add(entity);
156 }
157 else if(bulkEditorQuery != null){
158
159 IIdentifiableEntityServiceConfigurator configurator = bulkEditorQuery.getSearchConfigurator();
160 Comparator queryComparator = (bulkEditorQuery.getComparator() != null) ? bulkEditorQuery.getComparator() : new TitleCacheComparator();
161
162 String jobLabel = Messages.AbstractBulkEditorInput_LOADING+getName();
163 searchJob = Job.create(jobLabel, (ICoreRunnable) monitor -> {
164 monitor.beginTask(jobLabel, IProgressMonitor.UNKNOWN);
165 int pageNumber = 0;
166 List<T> entities;
167 do {
168 if (monitor.isCanceled()) {
169 break;
170 }
171 configurator.setPageNumber(pageNumber);
172 entities = listEntities(configurator);
173 model.addAll(entities);
174 pageNumber++;
175 Collections.sort(model, queryComparator);
176 } while (!entities.isEmpty());
177 monitor.done();
178 });
179 searchJob.schedule();
180 }
181 }
182
183 public boolean isMergingEnabled() {
184 return false;
185 }
186
187 public boolean isConvertingEnabled() {
188 return false;
189 }
190
191 public boolean isMarkerTypeEditingEnabled(MarkerType markerType) {
192 return false;
193 }
194
195
196 /** {@inheritDoc} */
197 @Override
198 public boolean merge(T entity, T mergeTarget) {
199 if (entity instanceof IMergable) {
200 try {
201 CdmStore.getCommonService().merge(mergeTarget.getUuid(), entity.getUuid(), (Class<? extends CdmBase>)entity.getClass());
202 } catch (MergeException e) {
203 MessagingUtils.errorDialog(Messages.AbstractBulkEditorInput_MERGE_ERROR_TITLE,
204 this,
205 String.format(Messages.AbstractBulkEditorInput_MERGE_ERROR_MESSAGE, entity.getClass().getName()),
206 TaxeditorBulkeditorPlugin.PLUGIN_ID,
207 e,
208 true);
209 }
210 }
211 return true;
212 }
213
214 public void saveModel(){
215 saveModel(true);
216 }
217
218 public void saveModel(boolean resetMerge){
219 //delete entities
220 for(Entry<T, DeleteConfiguratorBase> entry:toDelete.entrySet()){
221 try {
222 delete(entry.getKey(), entry.getValue());
223 } catch (ReferencedObjectUndeletableException e) {
224 e.printStackTrace();
225 }
226 }
227 toDelete.clear();
228 if (!saveCandidates.isEmpty()){
229 CdmStore.getService(saveCandidates.get(0)).merge(saveCandidates, true);
230 }
231 if(resetMerge){
232 //merge entities
233 for(T mergeTarget:mergedEntities.keySet()){
234 for (T mergeCandidate: mergedEntities.get(mergeTarget)){
235 merge(mergeCandidate, mergeTarget);
236 }
237 }
238 mergedEntities.clear();
239
240 }
241 }
242
243
244 /** {@inheritDoc} */
245 @Override
246 public T create(T entity) {
247 return save(entity);
248 }
249
250 public IEntityCreator<T> getEntityCreator(){
251 if(entityCreator == null){
252 entityCreator = createEntityCreator();
253 }
254 return entityCreator;
255 }
256
257 protected abstract IEntityCreator<T> createEntityCreator();
258
259 /**
260 * The default implementation returns an empty list of sort providers.
261 * @return
262 */
263 public List<IBulkEditorSortProvider<T>> getSortProviders(){
264 List<IBulkEditorSortProvider<T>> sortProviders = new ArrayList<IBulkEditorSortProvider<T>>();
265
266 sortProviders.add(new CdmBaseSortProvider<T>());
267
268 return sortProviders;
269 }
270
271 /**
272 * Returns a textual representation given object. The default implementation
273 * in the abstract base class returns the simple name of the class, this may
274 * be overwritten to something more specific in subclasses.
275 *
276 * @param entity
277 * @return a textual representation given object.
278 */
279 public String getTypeText(Object entity){
280 return entity.getClass().getSimpleName();
281 }
282
283 public String getText(T entity) {
284 if(entity instanceof IdentifiableEntity){
285 IdentifiableEntity identifiableEntity = (IdentifiableEntity) HibernateProxyHelper.deproxy(entity);
286 String text = ""; //$NON-NLS-1$
287 if(markedMergeCandidates.contains(entity)){
288 text += Messages.AbstractBulkEditorInput_CANDIDATE;
289 }
290 else if(markedMergeTarget==entity){
291 text += Messages.AbstractBulkEditorInput_TARGET;
292 }
293 text += identifiableEntity.getTitleCache();
294 return text;
295 }
296
297 return "No text. Implement in subclass"; //$NON-NLS-1$
298 }
299
300 public BasicEventList<T> getModel() {
301 return model;
302 }
303
304 protected boolean replaceInModel(T entity) {
305 int index = model.indexOf(entity);
306 if(index >= 0) {
307 model.set(index, entity);
308 return true;
309 } else {
310 return false;
311 }
312 }
313
314 @Override
315 public List<T> getRootEntities() {
316 return getModel();
317 }
318
319
320 @Override
321 public Map<Object, List<String>> getPropertyPathsMap() {
322 // TODO Auto-generated method stub
323 return null;
324 }
325
326 public ConversationHolder getConversation() {
327 return conversation;
328 }
329
330 public List<T> getSaveCandidates() {
331 return saveCandidates;
332 }
333
334 /**
335 *
336 */
337 public void resetSaveCandidates() {
338 this.saveCandidates.clear();
339
340 }
341
342 public HashMap<T, Set<T>> getMergedEntities() {
343 return mergedEntities;
344 }
345
346 public void setMergedEntities(HashMap<T, Set<T>> mergedEntities) {
347 this.mergedEntities = mergedEntities;
348 }
349 }