commit 53b63498112961442664224c65d560ef04de23ff
Author: Patrick Plitzner <p.plitzner@bgbm.org>
Date:   Tue Dec 4 10:17:41 2018 +0100

    ref #7923 Use character transfer instead of LocalSelectionTransfer

diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterDragListener.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterDragListener.java
index 9bacf141c..c3a4893e6 100644
--- a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterDragListener.java
+++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterDragListener.java
@@ -8,15 +8,16 @@
 */
 package eu.etaxonomy.taxeditor.editor.descriptiveDataSet.character;
 
-import java.util.List;
+import java.util.Collection;
 
-import org.eclipse.jface.util.LocalSelectionTransfer;
-import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.TreeSelection;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.swt.dnd.DragSourceEvent;
 
 import eu.etaxonomy.cdm.model.description.Character;
+import eu.etaxonomy.cdm.model.description.FeatureNode;
+import eu.etaxonomy.taxeditor.featuretree.CharacterTransfer;
 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDragListener;
 
 /**
@@ -42,10 +43,26 @@ public class CharacterDragListener extends FeatureNodeDragListener {
         if(structureSelection!=null && propertySelection!=null
                 && !structureSelection.isEmpty() && !propertySelection.isEmpty()){
             //create all possible characters
-            List<Character> characters = CharacterEditor.createCharacters(structureSelection, propertySelection);
+            Collection<Character> characters = CharacterEditor.createCharacters(structureSelection, propertySelection);
 
-            LocalSelectionTransfer.getTransfer().setSelection(new StructuredSelection(characters));
+            if (CharacterTransfer.getInstance().isSupportedType(event.dataType)) {
+                event.data = characters;
+            }
         }
     }
 
+    /**
+     * Method declared on DragSourceListener
+     */
+    @Override
+    public void dragStart(DragSourceEvent event) {
+        event.doit =
+                !structureViewer.getSelection().isEmpty()
+                && !propertyViewer.getSelection().isEmpty()
+                && ((IStructuredSelection) structureViewer.getSelection()).toList()
+                .stream().allMatch(element -> element instanceof FeatureNode)
+                && ((IStructuredSelection) propertyViewer.getSelection()).toList()
+                .stream().allMatch(element -> element instanceof FeatureNode);
+    }
+
 }
diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterDropAdapter.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterDropAdapter.java
index 756d55b83..8744a5039 100644
--- a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterDropAdapter.java
+++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterDropAdapter.java
@@ -8,12 +8,7 @@
 */
 package eu.etaxonomy.taxeditor.editor.descriptiveDataSet.character;
 
-import java.util.Iterator;
-
 import org.eclipse.e4.ui.di.UISynchronize;
-import org.eclipse.jface.util.LocalSelectionTransfer;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.swt.dnd.DropTargetEvent;
 import org.eclipse.swt.dnd.TransferData;
@@ -22,6 +17,7 @@ import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
 import eu.etaxonomy.cdm.model.description.Character;
 import eu.etaxonomy.cdm.model.description.FeatureNode;
 import eu.etaxonomy.cdm.model.description.FeatureTree;
+import eu.etaxonomy.taxeditor.featuretree.CharacterTransfer;
 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeDropAdapter;
 import eu.etaxonomy.taxeditor.featuretree.e4.IFeatureTreeEditor;
 import eu.etaxonomy.taxeditor.store.CdmStore;
@@ -46,45 +42,39 @@ public class CharacterDropAdapter extends FeatureTreeDropAdapter {
 
 	@Override
 	public boolean performDrop(Object data) {
+	    if(!CharacterTransfer.getInstance().isSupportedType(getCurrentEvent().currentDataType)){
+	        return super.performDrop(data);
+	    }
 	    if(StoreUtil.checkDirty(editor)){
 	        return false;
 	    }
 	    FeatureNode target = (FeatureNode) getCurrentTarget();
-	    ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
-	    if(selection!=null
-	            &&selection instanceof IStructuredSelection
-	            ){
-	        IStructuredSelection structuredSelection = (IStructuredSelection)selection;
-	        Iterator iterator = structuredSelection.iterator();
-	        while(iterator.hasNext()){
-	            Object next = iterator.next();
-	            if(next instanceof Character){
-	                Character character = (Character)next;
+	    if(data instanceof Object[]){
+	        Object[] transferObjects = (Object[])data;
+	        for(int i=0;i<transferObjects.length;i++){
+	            Object object = transferObjects[i];
+	            if(object instanceof Character){
+	                Character character = (Character)object;
 	                if(target==null){
-	                    //drop on feature tree
-	                    target = ((FeatureTree)getViewer().getInput()).getRoot();
-	                }
-	                CdmStore.getService(IFeatureNodeService.class).addChildFeatureNode(target.getUuid(), character.getUuid());
+                        //drop on feature tree
+                        target = ((FeatureTree)getViewer().getInput()).getRoot();
+                    }
+                    CdmStore.getService(IFeatureNodeService.class).createChildFeatureNode(target, character);
 	            }
 	        }
 	        getViewer().refresh();
-	        LocalSelectionTransfer.getTransfer().setSelection(null);
 	        return true;
 	    }
-	    return super.performDrop(data);
+	    return false;
 	}
 
 	@Override
 	public boolean validateDrop(Object target, int operation,
 			TransferData transferData) {
-		LocalSelectionTransfer transfer = LocalSelectionTransfer.getTransfer();
-        boolean valid = true;
-		valid &= transfer.getSelection()!=null
-		        && !transfer.getSelection().isEmpty();
-		if(!valid){
-		    return super.validateDrop(target, operation, transferData);
+		if(CharacterTransfer.getInstance().isSupportedType(transferData)){
+		    return true;
 		}
-		return valid;
+		return super.validateDrop(target, operation, transferData);
 	}
 
 }
diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterEditor.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterEditor.java
index 5a22bfdf8..abb9de6ce 100644
--- a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterEditor.java
+++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterEditor.java
@@ -11,10 +11,13 @@ package eu.etaxonomy.taxeditor.editor.descriptiveDataSet.character;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
@@ -35,6 +38,7 @@ import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.jface.viewers.TreeSelection;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.dnd.Transfer;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.events.SelectionAdapter;
@@ -52,13 +56,14 @@ import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
 import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
 import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
 import eu.etaxonomy.cdm.api.service.ITermService;
-import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
 import eu.etaxonomy.cdm.model.description.Character;
 import eu.etaxonomy.cdm.model.description.FeatureNode;
 import eu.etaxonomy.cdm.model.description.FeatureTree;
 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
 import eu.etaxonomy.taxeditor.editor.AppModelId;
 import eu.etaxonomy.taxeditor.editor.l10n.Messages;
+import eu.etaxonomy.taxeditor.featuretree.CharacterTransfer;
+import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDragListener;
 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeDropAdapter;
 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditorComposite;
@@ -135,7 +140,7 @@ public class CharacterEditor implements IFeatureTreeEditor,IConversationEnabled,
         composite.setLayout(gl_composite);
 
         structuresTreeEditorComposite = addFeatureTreeEditor(composite);
-        initFeatureTreeComposite(structuresTreeEditorComposite, null, null);
+        initFeatureTreeComposite(structuresTreeEditorComposite, null, null, null);
         structuresTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_STRUCTURES);
 
         Composite composite_1 = new Composite(sashForm, SWT.NONE);
@@ -146,7 +151,12 @@ public class CharacterEditor implements IFeatureTreeEditor,IConversationEnabled,
         composite_1.setLayout(gl_composite_1);
 
         propertiesTreeEditorComposite = addFeatureTreeEditor(composite_1);
-        initFeatureTreeComposite(propertiesTreeEditorComposite, new CharacterDragListener(structuresTreeEditorComposite.getViewer(), propertiesTreeEditorComposite.getViewer()), null);
+        initFeatureTreeComposite(propertiesTreeEditorComposite,
+                new CharacterDragListener(structuresTreeEditorComposite.getViewer(),
+                        propertiesTreeEditorComposite.getViewer()),
+                null,
+                new Transfer[] {CharacterTransfer.getInstance()}
+        );
         propertiesTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_PROPERTIES);
 
         Composite composite_3 = new Composite(sashForm, SWT.NONE);
@@ -161,7 +171,9 @@ public class CharacterEditor implements IFeatureTreeEditor,IConversationEnabled,
         formToolkit.adapt(btnAddCharacter, true, true);
 
         characterTreeEditorComposite = addFeatureTreeEditor(composite_3);
-        initFeatureTreeComposite(characterTreeEditorComposite, new FeatureNodeDragListener(characterTreeEditorComposite.getViewer()), new CharacterDropAdapter(this, characterTreeEditorComposite.getViewer(), sync));
+        initFeatureTreeComposite(characterTreeEditorComposite, new FeatureNodeDragListener(characterTreeEditorComposite.getViewer()),
+                new CharacterDropAdapter(this, characterTreeEditorComposite.getViewer(), sync),
+                new Transfer[] {FeatureNodeTransfer.getInstance(), CharacterTransfer.getInstance()});
         characterTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_CHARACTERS);
 
         //add context menu to character viewer//create context menu
@@ -177,10 +189,18 @@ public class CharacterEditor implements IFeatureTreeEditor,IConversationEnabled,
         return featureTreeEditorComposite;
     }
 
-    private void initFeatureTreeComposite(FeatureTreeEditorComposite featureTreeEditorComposite,
-            FeatureNodeDragListener featureNodeDragListener, FeatureTreeDropAdapter featureNodeDropAdapter) {
-        featureTreeEditorComposite.init(featureNodeDragListener, featureNodeDropAdapter, this,
-                new FeatureTreeChooserListener(featureTreeEditorComposite), this);
+    private void initFeatureTreeComposite(
+            FeatureTreeEditorComposite featureTreeEditorComposite,
+            FeatureNodeDragListener featureNodeDragListener,
+            FeatureTreeDropAdapter featureNodeDropAdapter
+            , Transfer[] transfers) {
+        featureTreeEditorComposite.init(
+                featureNodeDragListener,
+                featureNodeDropAdapter,
+                transfers,
+                this,
+                new FeatureTreeChooserListener(featureTreeEditorComposite),
+                this);
     }
 
     @Focus
@@ -210,7 +230,7 @@ public class CharacterEditor implements IFeatureTreeEditor,IConversationEnabled,
                             Messages.CharacterEditor_CANNOT_PERFORM_MESSAGE);
                     return;
                 }
-                List<Character> characters = createCharacters((TreeSelection)structureTreeSelection, (TreeSelection)propertyTreeSelection);
+                Collection<Character> characters = createCharacters((TreeSelection)structureTreeSelection, (TreeSelection)propertyTreeSelection);
                 for (Character character : characters) {
                     //add new Character to feature tree
                     FeatureNode parent = ((FeatureTree) characterTreeEditorComposite.getViewer().getInput()).getRoot();
@@ -223,8 +243,8 @@ public class CharacterEditor implements IFeatureTreeEditor,IConversationEnabled,
         });
     }
 
-    public static List<Character> createCharacters(TreeSelection structureTreeSelection, TreeSelection propertyTreeSelection){
-        List<Character> characters = new ArrayList<>();
+    public static Collection<Character> createCharacters(TreeSelection structureTreeSelection, TreeSelection propertyTreeSelection){
+        Set<Character> characters = new HashSet<>();
         //get selected structures and properties
         Iterator<FeatureNode> structureIterator = structureTreeSelection.iterator();
 
@@ -235,9 +255,8 @@ public class CharacterEditor implements IFeatureTreeEditor,IConversationEnabled,
             while(propertiesIterator.hasNext()){
                 FeatureNode propertyNode = propertiesIterator.next();
                 //create new Character
-                String label = structureNode.getFeature().generateTitle()+" "+propertyNode.getFeature().generateTitle(); //$NON-NLS-1$
-                Character character = Character.NewInstance(structureNode, propertyNode, "", label, label); //$NON-NLS-1$
-                characters.add(HibernateProxyHelper.deproxy(CdmStore.getService(ITermService.class).save(character), Character.class));
+                Character character = Character.NewInstance(structureNode, propertyNode);
+                characters.add(character);
             }
         }
         return characters;
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/CharacterTransfer.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/CharacterTransfer.java
new file mode 100644
index 000000000..e361489f2
--- /dev/null
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/CharacterTransfer.java
@@ -0,0 +1,115 @@
+/**
+* Copyright (C) 2018 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.featuretree;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import org.eclipse.swt.dnd.ByteArrayTransfer;
+import org.eclipse.swt.dnd.TransferData;
+
+import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
+import eu.etaxonomy.cdm.model.description.Character;
+import eu.etaxonomy.cdm.model.description.FeatureNode;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+
+/**
+ * @author pplitzner
+ * @since Nov 30, 2018
+ *
+ */
+public class CharacterTransfer extends ByteArrayTransfer {
+
+    private static CharacterTransfer instance = new CharacterTransfer();
+    private static final String TYPE_NAME = "characters-transfer-format";
+    private static final int TYPEID = registerType(TYPE_NAME);
+
+
+    public static synchronized CharacterTransfer getInstance() {
+        return instance;
+    }
+
+    private CharacterTransfer() {
+    }
+
+    @Override
+    protected int[] getTypeIds() {
+        return new int[] { TYPEID };
+    }
+
+    @Override
+    protected String[] getTypeNames() {
+        return new String[] { TYPE_NAME };
+    }
+
+    @Override
+    protected void javaToNative(Object object, TransferData transferData) {
+        if (object != null){
+            Collection<Character> characters = (Collection<Character>)object;
+            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+            DataOutputStream out = new DataOutputStream(byteOut);
+
+            byte[] bytes = null;
+
+            try {
+
+                for(Character character : characters){
+                    out.writeUTF(character.getStructure().getUuid().toString()
+                            +","
+                            +character.getProperty().getUuid().toString());
+                }
+                out.close();
+                bytes = byteOut.toByteArray();
+            } catch (IOException e) {
+                // when in doubt send nothing
+            }
+            if (bytes != null) {
+                super.javaToNative(bytes, transferData);
+            }
+        }
+    }
+
+    @Override
+    protected Object nativeToJava(TransferData transferData) {
+        byte[] bytes = (byte[]) super.nativeToJava(transferData);
+        if (bytes != null){
+            DataInputStream in = new DataInputStream(
+                    new ByteArrayInputStream(bytes));
+
+            try {
+                List<Character> characters = new ArrayList<>();
+
+                try{
+                    while(true){
+                        String string = in.readUTF();
+                        String[] split = string.split(",");
+                        IFeatureNodeService featureNodeService = CdmStore.getService(IFeatureNodeService.class);
+                        FeatureNode structure = featureNodeService.load(UUID.fromString(split[0]));
+                        FeatureNode property = featureNodeService.load(UUID.fromString(split[1]));
+                        characters.add(Character.NewInstance(structure, property));
+                    }
+                }catch(EOFException e){
+                    return characters.toArray();
+                }
+            } catch (IOException e) {
+                return null;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureTreeEditorComposite.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureTreeEditorComposite.java
index 972336135..2fb8923ab 100644
--- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureTreeEditorComposite.java
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureTreeEditorComposite.java
@@ -8,7 +8,6 @@
 */
 package eu.etaxonomy.taxeditor.featuretree.e4;
 
-import org.eclipse.jface.util.LocalSelectionTransfer;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.swt.SWT;
@@ -84,23 +83,41 @@ public class FeatureTreeEditorComposite extends Composite{
                 new GridData(SWT.FILL, SWT.FILL, true, true));
     }
 
-    public void init(String label, DragSourceListener dragSourceListener, DropTargetListener dropTargetListener,
-            ISelectionChangedListener viewerSelectionChangedListener, IDirtyMarkable dirtyMarkable,
+    public void init(String label,
+            DragSourceListener dragSourceListener,
+            DropTargetListener dropTargetListener,
+            ISelectionChangedListener viewerSelectionChangedListener,
+            IDirtyMarkable dirtyMarkable,
             ModifyListener textModifyListener) {
-        this.init(label, dragSourceListener, dropTargetListener, viewerSelectionChangedListener, null, dirtyMarkable,
+        this.init(label,
+                dragSourceListener,
+                dropTargetListener,
+                null,
+                viewerSelectionChangedListener,
+                null,
+                dirtyMarkable,
                 textModifyListener);
     }
-    public void init(DragSourceListener dragSourceListener, DropTargetListener dropTargetListener,
+    public void init(DragSourceListener dragSourceListener,
+            DropTargetListener dropTargetListener,
+            Transfer[] transfers,
             ISelectionChangedListener viewerSelectionChangedListener,
             SelectionListener openFeatureTreeSelectionListener,
             ModifyListener textModifyListener) {
-        init(null, dragSourceListener, dropTargetListener, viewerSelectionChangedListener, openFeatureTreeSelectionListener,
-                null, textModifyListener);
+        init(null, dragSourceListener,
+                dropTargetListener,
+                transfers,
+                viewerSelectionChangedListener,
+                openFeatureTreeSelectionListener,
+                null,
+                textModifyListener);
     }
     private void init(String label, DragSourceListener dragSourceListener,
             DropTargetListener dropTargetListener,
+            Transfer[] transfers,
             ISelectionChangedListener viewerSelectionChangedListener,
-            SelectionListener openFeatureTreeSelectionListener, IDirtyMarkable dirtyMarkable,
+            SelectionListener openFeatureTreeSelectionListener,
+            IDirtyMarkable dirtyMarkable,
             ModifyListener textModifyListener) {
         if(label!=null){
             label_title.setText(label);
@@ -110,11 +127,12 @@ public class FeatureTreeEditorComposite extends Composite{
         viewer.setLabelProvider(new FeatureTreeLabelProvider());
 
         int ops = DND.DROP_COPY | DND.DROP_MOVE;
-        Transfer[] transfers = new Transfer[] {
+        if(transfers==null){
+        transfers = new Transfer[] {
                 FeatureNodeTransfer.getInstance(),
                 TermTransfer.getInstance(),
-                LocalSelectionTransfer.getTransfer()
                 };
+        }
         if(dragSourceListener!=null){
             viewer.addDragSupport(ops, transfers, dragSourceListener);
         }
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/newWizard/NewPolytomousKeyWizard.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/newWizard/NewPolytomousKeyWizard.java
index aaa3fe3ab..23cca956b 100644
--- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/newWizard/NewPolytomousKeyWizard.java
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/newWizard/NewPolytomousKeyWizard.java
@@ -4,6 +4,7 @@
 package eu.etaxonomy.taxeditor.newWizard;
 
 import eu.etaxonomy.cdm.api.service.IPolytomousKeyService;
+import eu.etaxonomy.cdm.common.CdmUtils;
 import eu.etaxonomy.cdm.model.description.PolytomousKey;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 
@@ -30,7 +31,7 @@ public class NewPolytomousKeyWizard extends AbstractNewEntityWizard<PolytomousKe
 	 */
 	@Override
 	protected void saveEntity() {
-	    if(!polytomousKeyPage.getPolytomousKeyName().equals("")) {
+	    if(CdmUtils.isNotBlank(polytomousKeyPage.getPolytomousKeyName())) {
 	        CdmStore.getService(IPolytomousKeyService.class).merge(getEntity(), true);
 	    }
 	}
@@ -50,4 +51,12 @@ public class NewPolytomousKeyWizard extends AbstractNewEntityWizard<PolytomousKe
 		return "Polytomous Key";
 	}
 
+	@Override
+	public boolean canFinish() {
+        if(CdmUtils.isBlank(polytomousKeyPage.getPolytomousKeyName())) {
+            return false;
+        }
+	    return super.canFinish();
+	}
+
 }
