X-Git-Url: https://dev.e-taxonomy.eu/gitweb/taxeditor.git/blobdiff_plain/533fd1e86c8ba04a3c7c4b36915df72cf83c1cbd..6ce970f79952ed25b2037fbea1a19803b514985a:/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AbstractBulkEditorInput.java diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AbstractBulkEditorInput.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AbstractBulkEditorInput.java index ffb762dc4..747dc3df6 100644 --- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AbstractBulkEditorInput.java +++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AbstractBulkEditorInput.java @@ -9,7 +9,7 @@ package eu.etaxonomy.taxeditor.bulkeditor.input; import java.util.ArrayList; -import java.util.Collections; +import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -18,10 +18,11 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; import org.eclipse.core.runtime.ICoreRunnable; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.viewers.IStructuredSelection; import ca.odell.glazedlists.BasicEventList; import eu.etaxonomy.cdm.api.conversation.ConversationHolder; @@ -32,6 +33,7 @@ import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; import eu.etaxonomy.cdm.model.common.CdmBase; import eu.etaxonomy.cdm.model.common.IdentifiableEntity; import eu.etaxonomy.cdm.model.common.MarkerType; +import eu.etaxonomy.cdm.persistence.dto.MergeResult; import eu.etaxonomy.cdm.strategy.merge.IMergable; import eu.etaxonomy.cdm.strategy.merge.MergeException; import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityCreator; @@ -42,6 +44,8 @@ import eu.etaxonomy.taxeditor.bulkeditor.input.sortprovider.CdmBaseSortProvider; import eu.etaxonomy.taxeditor.bulkeditor.input.sortprovider.TitleCacheComparator; import eu.etaxonomy.taxeditor.bulkeditor.internal.TaxeditorBulkeditorPlugin; import eu.etaxonomy.taxeditor.editor.CdmEntitySessionInput; +import eu.etaxonomy.taxeditor.event.EventUtility; +import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants; import eu.etaxonomy.taxeditor.l10n.Messages; import eu.etaxonomy.taxeditor.model.MessagingUtils; import eu.etaxonomy.taxeditor.store.CdmStore; @@ -49,18 +53,27 @@ import eu.etaxonomy.taxeditor.store.CdmStore; /** * @author p.ciardelli * @created 25.06.2009 - * @version 1.0 - * @param */ -public abstract class AbstractBulkEditorInput extends CdmEntitySessionInput implements - IEntityPersistenceService { +public abstract class AbstractBulkEditorInput + extends CdmEntitySessionInput + implements IEntityPersistenceService { + + + private static final String PROPERTY_PROTECTED_TITLECACHE = "Protect TitleCache"; + private static final String TYPE_PROPERTY = Messages.BulkEditorE4_TYPE; + private static final String ID_PROPERTY = "Id"; //$NON-NLS-1$ + private static final String UUID_PROPERTY = "Uuid"; //$NON-NLS-1$ private UUID entityUuid; private BasicEventList model = new BasicEventList<>(); private Map toDelete = new HashMap<>(); - private List saveCandidates = new ArrayList<>(); + public Map getToDelete() { + return toDelete; + } + + private Set saveCandidates = new HashSet<>(); private Set markedMergeCandidates = new HashSet<>(); @@ -87,23 +100,92 @@ public abstract class AbstractBulkEditorInput extends CdmEnti BulkEditorInputType inputType = BulkEditorInputType.getByType(entity.getClass()); - AbstractBulkEditorInput editorInput = NewInstance(inputType); + AbstractBulkEditorInput editorInput = NewInstance(inputType); editorInput.setEntityUuid(entity.getUuid()); return editorInput; } + public static AbstractBulkEditorInput NewInstance(Class clazz, UUID uuid) { + + BulkEditorInputType inputType = BulkEditorInputType.getByType(clazz); + + AbstractBulkEditorInput editorInput = NewInstance(inputType); + + editorInput.setEntityUuid(uuid); + + return editorInput; + } + public abstract String getName(); public String getEditorName(){ return getName(); } + protected int getPageSize(){ + return 100; + } + protected abstract List listEntities(IIdentifiableEntityServiceConfigurator configurator); + protected abstract long countEntities(IIdentifiableEntityServiceConfigurator configurator); + protected abstract T loadEntity(UUID entityUuid); + public List getPropertyKeys(){ + List properties = new ArrayList<>(); + properties.add(getName()); + properties.add(PROPERTY_PROTECTED_TITLECACHE); + properties.addAll(getPropertyKeys_internal()); + properties.add(TYPE_PROPERTY); + properties.add(ID_PROPERTY); + properties.add(UUID_PROPERTY); + return properties; + } + + protected abstract List getPropertyKeys_internal(); + + + public Object getPropertyValue(T cdmBase, String property){ + if(property.equals(getName())){ + return getText(cdmBase); + } + else if(property.equals(PROPERTY_PROTECTED_TITLECACHE) + &&cdmBase.isInstanceOf(IdentifiableEntity.class)){ + return HibernateProxyHelper.deproxy(cdmBase, IdentifiableEntity.class).isProtectedTitleCache(); + } + else if(property.equals(TYPE_PROPERTY)){ + return getTypeText(cdmBase); + } + else if(property.equals(UUID_PROPERTY)){ + return cdmBase.getUuid(); + } + else if(property.equals(ID_PROPERTY)){ + return cdmBase.getId(); + } + return null; + } + + public boolean isBooleanProperty(String property) { + if(property.equals(PROPERTY_PROTECTED_TITLECACHE)){ + return true; + } + return false; + } + + public boolean isCacheProperty(String property) { + if(property.equals(PROPERTY_PROTECTED_TITLECACHE)){ + return true; + } + return false; + } + + public Comparator getTitleComparator(){ + return new TitleCacheComparator(); + } + public void setMergeTarget(T t){ markedMergeTarget = t; } @@ -134,7 +216,7 @@ public abstract class AbstractBulkEditorInput extends CdmEnti public void addSaveCandidate(T t){ saveCandidates.add(t); } - private void setEntityUuid(UUID entityUuid){ + public void setEntityUuid(UUID entityUuid){ this.entityUuid = entityUuid; } @@ -142,44 +224,115 @@ public abstract class AbstractBulkEditorInput extends CdmEnti return entityUuid; } - public void performSearch(final BulkEditorQuery bulkEditorQuery) { + public void performSearch(final BulkEditorQuery bulkEditorQuery, IStructuredSelection selection) { + //cancel previous search job if(searchJob!=null && searchJob.getState()!=Job.NONE){ - MessagingUtils.informationDialog(Messages.AbstractBulkEditorInput_MULTIPLE_SEARCH_TITLE, Messages.AbstractBulkEditorInput_MULTIPLE_SEARCH_MESSAGE); - return; + boolean isCanceled = searchJob.cancel(); + if (!isCanceled){ + while (!isCanceled){ + try { + Thread.sleep(200); + } catch (InterruptedException e) { + } + isCanceled = searchJob.cancel(); + } + } + searchJob = null; +// /* +// * wait for a little while for the job to finish +// * to avoid asynchronously loaded results of the +// * previous search being shown in the next search +// * (not critical but explicitly waiting for the job to finish +// * could run into an endless loop by mistake) +// */ +// try { +// Thread.sleep(500); +// } catch (InterruptedException e) { +// } } - model.clear(); + model.clear(); + markedMergeCandidates.clear(); + markedMergeTarget = null; if(getEntityUuid() != null){ - T entity = loadEntity(getEntityUuid()); model.add(entity); } else if(bulkEditorQuery != null){ + IIdentifiableEntityServiceConfigurator configurator = bulkEditorQuery.getSearchConfigurator(); + + // check for UUID search + String titleSearchString = configurator.getTitleSearchString(); + try { + UUID uuid = UUID.fromString(titleSearchString); + T entity = loadEntity(uuid); + //UUID search found -> add entity to list and return + model.add(entity); + return; + } catch (IllegalArgumentException e) { + // search string was no UUID + } + //-> continue with standard search - IIdentifiableEntityServiceConfigurator configurator = bulkEditorQuery.getSearchConfigurator(); - Comparator queryComparator = (bulkEditorQuery.getComparator() != null) ? bulkEditorQuery.getComparator() : new TitleCacheComparator(); - - String jobLabel = Messages.AbstractBulkEditorInput_LOADING+getName(); + int pageSize = configurator.getPageSize()!=null?configurator.getPageSize():getPageSize(); + configurator.setPageSize(pageSize); + long count = countEntities(configurator); + int totalWork = count>Integer.MAX_VALUE?Integer.MAX_VALUE:(int)count; + String jobLabel = String.format(Messages.AbstractBulkEditorInput_LOADING, getName(), bulkEditorQuery.getSearchString()); searchJob = Job.create(jobLabel, (ICoreRunnable) monitor -> { - monitor.beginTask(jobLabel, IProgressMonitor.UNKNOWN); + monitor.beginTask(jobLabel, totalWork); int pageNumber = 0; - List entities = listEntities(configurator); - while(!entities.isEmpty()){ - if(monitor.isCanceled()){ - break; - } - configurator.setPageNumber(pageNumber); - entities = listEntities(configurator); - model.addAll(entities); - pageNumber++; - Collections.sort(model, queryComparator); + List entities; + + //load previously selected element + UUID selectedUuid = null; + if(selection!=null && selection.getFirstElement() instanceof CdmBase){ + selectedUuid = ((CdmBase) selection.getFirstElement()).getUuid(); + T entity = loadEntity(selectedUuid); + model.add(entity); } + + do { + if (monitor.isCanceled()) { + break; + } + configurator.setPageNumber(pageNumber); + entities = listEntities(configurator); + + addToModel(entities, selectedUuid); + + pageNumber++; + monitor.worked(pageSize); + long workedLong = pageSize*pageNumber; + int loadedCount = workedLong>Integer.MAX_VALUE?Integer.MAX_VALUE:(int)workedLong; + monitor.setTaskName(String.format(Messages.AbstractBulkEditorInput_LOADED, loadedCount, totalWork, getName())); + + //Update selection + EventUtility.postAsyncEvent(WorkbenchEventConstants.BULK_EDITOR_SEARCH_FINISHED, selection); + } while (!entities.isEmpty()); monitor.done(); + EventUtility.postAsyncEvent(WorkbenchEventConstants.BULK_EDITOR_SEARCH_FINISHED, selection); }); searchJob.schedule(); } } + private void addToModel(List entities, UUID selectedUuid){ + //filter pre-loaded previously selected element + if(selectedUuid!=null){ + entities = entities.stream().filter(entity->!entity.getUuid().equals(selectedUuid)).collect(Collectors.toList()); + } + /* + * IMPORTANT! + * Entities have to be loaded into the main session because they are + * loaded in a parallel asynchronous thread + */ + if(getCdmEntitySession()!=null){//is null when closing the bulk editor during loading + getCdmEntitySession().load(entities, true); + } + model.addAll(entities); + } + public boolean isMergingEnabled() { return false; } @@ -192,8 +345,6 @@ public abstract class AbstractBulkEditorInput extends CdmEnti return false; } - - /** {@inheritDoc} */ @Override public boolean merge(T entity, T mergeTarget) { if (entity instanceof IMergable) { @@ -224,9 +375,13 @@ public abstract class AbstractBulkEditorInput extends CdmEnti e.printStackTrace(); } } - toDelete.clear(); if (!saveCandidates.isEmpty()){ - CdmStore.getService(saveCandidates.get(0)).merge(saveCandidates, true); + List> results = CdmStore.getService(saveCandidates.iterator().next()).merge(new ArrayList<>(saveCandidates), true); + for (MergeResult result: results){ + if (result.getMergedEntity() != null){ + T entity = result.getMergedEntity(); + } + } } if(resetMerge){ //merge entities @@ -235,13 +390,12 @@ public abstract class AbstractBulkEditorInput extends CdmEnti merge(mergeCandidate, mergeTarget); } } - mergedEntities.clear(); - } + toDelete.clear(); + saveCandidates.clear(); + mergedEntities.clear(); } - - /** {@inheritDoc} */ @Override public T create(T entity) { return save(entity); @@ -261,9 +415,9 @@ public abstract class AbstractBulkEditorInput extends CdmEnti * @return */ public List> getSortProviders(){ - List> sortProviders = new ArrayList>(); + List> sortProviders = new ArrayList<>(); - sortProviders.add(new CdmBaseSortProvider()); + sortProviders.add(new CdmBaseSortProvider<>()); return sortProviders; } @@ -281,16 +435,9 @@ public abstract class AbstractBulkEditorInput extends CdmEnti } public String getText(T entity) { - if(entity instanceof IdentifiableEntity){ - IdentifiableEntity identifiableEntity = (IdentifiableEntity) HibernateProxyHelper.deproxy(entity); - String text = ""; //$NON-NLS-1$ - if(markedMergeCandidates.contains(entity)){ - text += Messages.AbstractBulkEditorInput_CANDIDATE; - } - else if(markedMergeTarget==entity){ - text += Messages.AbstractBulkEditorInput_TARGET; - } - text += identifiableEntity.getTitleCache(); + if(entity.isInstanceOf(IdentifiableEntity.class)){ + IdentifiableEntity identifiableEntity = HibernateProxyHelper.deproxy(entity, IdentifiableEntity.class); + String text = identifiableEntity.getTitleCache(); return text; } @@ -301,7 +448,7 @@ public abstract class AbstractBulkEditorInput extends CdmEnti return model; } - protected boolean replaceInModel(T entity) { + public boolean replaceInModel(T entity) { int index = model.indexOf(entity); if(index >= 0) { model.set(index, entity); @@ -312,7 +459,7 @@ public abstract class AbstractBulkEditorInput extends CdmEnti } @Override - public List getRootEntities() { + public Collection getRootEntities() { return getModel(); } @@ -327,18 +474,10 @@ public abstract class AbstractBulkEditorInput extends CdmEnti return conversation; } - public List getSaveCandidates() { + public Set getSaveCandidates() { return saveCandidates; } - /** - * - */ - public void resetSaveCandidates() { - this.saveCandidates.clear(); - - } - public HashMap> getMergedEntities() { return mergedEntities; } @@ -346,4 +485,5 @@ public abstract class AbstractBulkEditorInput extends CdmEnti public void setMergedEntities(HashMap> mergedEntities) { this.mergedEntities = mergedEntities; } + }