Author: bpoussin Date: 2016-11-29 17:22:02 +0100 (Tue, 29 Nov 2016) New Revision: 4375 Url: http://forge.codelutin.com/projects/isis-fish/repository/revisions/4375 Log: rewrite UI do use radio button Modified: trunk/src/main/java/fr/ifremer/isisfish/entities/RegionImportJson.java trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputHandler.java trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputSaveVerifier.java Modified: trunk/src/main/java/fr/ifremer/isisfish/entities/RegionImportJson.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/entities/RegionImportJson.java 2016-11-23 13:08:32 UTC (rev 4374) +++ trunk/src/main/java/fr/ifremer/isisfish/entities/RegionImportJson.java 2016-11-29 16:22:02 UTC (rev 4375) @@ -10,20 +10,27 @@ import fr.ifremer.isisfish.types.TimeUnit; import fr.ifremer.isisfish.util.EntitySemanticsDecorator; import fr.ifremer.isisfish.util.MatrixCSVHelper; +import java.awt.GridLayout; import java.io.IOException; import java.io.Reader; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; -import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import javax.swing.ButtonGroup; import javax.swing.JComboBox; import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JRadioButton; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.lang3.ClassUtils; import org.apache.commons.logging.Log; @@ -50,327 +57,6 @@ */ public class RegionImportJson { - /** - * Use during import to merge imported data in existing Region - */ - static public interface RegionMerge { - static public enum AnswerType { - NONE, REUSE, IMPORT, ABORT - }; - - static public class Answer { - public AnswerType type; - public TopiaEntity entity; - - public Answer(AnswerType type, TopiaEntity entity) { - this.type = type; - this.entity = entity; - } - - public boolean isAbort() { - return type == AnswerType.ABORT; - } - } - - /** - * Get last answer return by choice - * @return last answer return by previous call to choice - */ - public Answer getLastAnswer(); - - /** - * Ask how to merge entity - * @param id - * @param toString - * @param details - * @return - */ - public Answer choice(String id, String toString, Map<String, Object> details); - - /** - * If exist return entity in existing Region with id in parameter - * @param id - * @return null or TopiaEntity - */ - public TopiaEntity getEntity(String id); - } - - static public class RegionMergeDatabase implements RegionMerge { - static public enum ComplexeAnswerType { - NONE, NONE_THIS_TYPE, NONE_ALL, - REUSE, REUSE_THIS_TYPE, REUSE_ALL, - IMPORT, IMPORT_THIS_TYPE, IMPORT_ALL, - ABORT - }; - - /** - * Object used to keep recurent answer (abort, import All, reuse All, ...) - */ - static public class RegionMergeContext { - protected boolean abort = false; - protected boolean noneAll = false; - protected Set<Class> noneType = new HashSet<Class>(); - protected boolean reuseAll = false; - protected Set<Class> reuseType = new HashSet<Class>(); - protected boolean importAll = false; - protected Set<Class> importType = new HashSet<Class>(); - protected AnswerType lastAnswer = null; - protected TopiaEntity reuseEntity; - protected Class currentType; - - public RegionMergeContext() { - } - - public RegionMergeContext(boolean importAll) { - this.importAll = importAll; - } - - public RegionMerge.Answer getAnswer() { - RegionMerge.Answer result = null; - if (lastAnswer != null) { - result = new RegionMerge.Answer(lastAnswer, reuseEntity); - } - return result; - } - - public Class getCurrentType() { - return currentType; - } - - protected void setLastAnswer(ComplexeAnswerType lastAnswer) { - this.setLastAnswer(lastAnswer, null); - } - - protected void setLastAnswer(ComplexeAnswerType lastAnswer, TopiaEntity e) { - this.reuseEntity = e; - switch (lastAnswer) { - case NONE: - this.lastAnswer = AnswerType.NONE; - break; - case NONE_THIS_TYPE: - noneType.add(currentType); - this.lastAnswer = AnswerType.NONE; - break; - case NONE_ALL: - noneAll = true; - this.lastAnswer = AnswerType.NONE; - break; - case ABORT: - abort = true; - this.lastAnswer = AnswerType.ABORT; - break; - case IMPORT: - this.lastAnswer = AnswerType.IMPORT; - break; - case IMPORT_THIS_TYPE: - importType.add(currentType); - this.lastAnswer = AnswerType.IMPORT; - break; - case IMPORT_ALL: - importAll = true; - this.lastAnswer = AnswerType.IMPORT; - break; - case REUSE: - this.lastAnswer = AnswerType.REUSE; - break; - case REUSE_THIS_TYPE: - reuseType.add(currentType); - this.lastAnswer = AnswerType.REUSE; - break; - case REUSE_ALL: - reuseAll = true; - this.lastAnswer = AnswerType.REUSE; - break; - } - } - - public AnswerType initAnswer(Class type) { - lastAnswer = null; - currentType = type; - if (abort) { - lastAnswer = AnswerType.ABORT; - } else if (noneAll || noneType.contains(type)) { - lastAnswer = AnswerType.NONE; - } else if (importAll || importType.contains(type)) { - lastAnswer = AnswerType.IMPORT; - } - return lastAnswer; - } - - public AnswerType initAnswer(Class type, Set<TopiaEntity> possible) { - lastAnswer = null; - currentType = type; - if (possible != null && possible.size() == 1 && (reuseAll || reuseType.contains(type))) { - lastAnswer = AnswerType.REUSE; - this.reuseEntity = possible.iterator().next(); - } - return lastAnswer; - } - } - - - protected TopiaContext tx; - protected RegionMergeContext context; - protected Answer lastAnswer; - - public RegionMergeDatabase(TopiaContext tx) { - this.tx = tx; - } - - @Override - public Answer getLastAnswer() { - return lastAnswer; - } - - @Override - public TopiaEntity getEntity(String id) { - TopiaEntity result = tx.findByTopiaId(id); - return result; - } - - @Override - public Answer choice(String id, String toString, Map<String, Object> details) { - Class type = TopiaId.getClassName(id); - if (context == null) { - context = new RegionMergeContext(); - } - - if (context.initAnswer(type) == null) { - TopiaDAO<TopiaEntity> dao = IsisFishDAOHelper.getDAO(tx, type); - - LinkedHashSet<TopiaEntity> possible = new LinkedHashSet<TopiaEntity>(); - - possible.add(dao.findByTopiaId(id)); - if (Equation.class.isAssignableFrom(context.getCurrentType())) { - if (details.containsKey("name") && details.containsKey("category")) { - possible.addAll(dao.findAllByProperties("name", details.get("name"), "category", details.get("category"))); - } - } else { - if (details.containsKey("name")) { - possible.addAll(dao.findAllByProperty("name", details.get("name"))); - } - } - - if (context.initAnswer(type, possible) == null) { - if (Equation.class.isAssignableFrom(context.getCurrentType())) { - if (details.containsKey("category")) { - possible.addAll(dao.findAllByProperty("category", details.get("category"))); - } - } else { - possible.addAll(dao.findAll()); - } - - ask(context, toString, details, possible); - } - } - - return lastAnswer = context.getAnswer(); - } - - protected void ask(RegionMergeContext context, String toString, - Map<String, Object> details, Collection<TopiaEntity> possible) { - - JComboBox select = new JComboBox(possible.toArray()); - - Object[] options = new Object[] { - "None", // for null - "None same type", // for null - "None all", // for null - "Reuse selected object", - "Reuse same type", - "Reuse all", - "Import", - "Import same type", - "Import All", - "Abort" - }; - - - int result = JOptionPane.showOptionDialog(null, - new Object[]{ - String.format("You try to import '%s' (%s)", toString, - ClassUtils.getShortClassName(context.getCurrentType())), - "", - "Possible answer are:", - "None: don't import nor reuse an object.", - "None same type: auto response None for this answer and all next answer for same object type.", - "None all: auto response None for this answer and all next answer for all object type.", - "Reuse: use object already in current Region (make your choice in next combobox).", - select, - "Reuse same type: auto response Reuse for this answer and all next answer if only one object found ('id' or 'name') in current Region for this type.", - "Reuse all: auto response Reuse for this answer and all next answer if only one object found ('id' or 'name') in current Region for all object.", - "Import: import object from file.", - "Import same type: auto response Import for this answer and all next answer for same object type.", - "Import All: auto response Import for this answer and all next answer for all object.", - "Abort: Cancel this import (import nothing)." - }, - "Make a choice", - JOptionPane.DEFAULT_OPTION, - JOptionPane.QUESTION_MESSAGE, - null, - options, - options[0]); - - TopiaEntity selectEntity = (TopiaEntity)select.getSelectedItem(); - switch (result) { - case 0: - context.setLastAnswer(ComplexeAnswerType.NONE); - break; - case 1: - context.setLastAnswer(ComplexeAnswerType.NONE_THIS_TYPE); - break; - case 2: - context.setLastAnswer(ComplexeAnswerType.NONE_ALL); - break; - case 3: - context.setLastAnswer(ComplexeAnswerType.REUSE, selectEntity); - break; - case 4: - context.setLastAnswer(ComplexeAnswerType.REUSE_THIS_TYPE, selectEntity); - break; - case 5: - context.setLastAnswer(ComplexeAnswerType.REUSE_ALL, selectEntity); - break; - case 6: - context.setLastAnswer(ComplexeAnswerType.IMPORT); - break; - case 7: - context.setLastAnswer(ComplexeAnswerType.IMPORT_THIS_TYPE); - break; - case 8: - context.setLastAnswer(ComplexeAnswerType.IMPORT_ALL); - break; - case 9: - context.setLastAnswer(ComplexeAnswerType.ABORT); - break; - default: - ask(context, toString, details, possible); - break; - } - } - } - - static public class RegionMergeImportAll implements RegionMerge { - protected Answer lastAnswer; - - @Override - public Answer getLastAnswer() { - return lastAnswer; - } - - - @Override - public TopiaEntity getEntity(String id) { - return null; - } - - @Override - public Answer choice(String id, String toString, Map<String, Object> details) { - return lastAnswer = new Answer(AnswerType.IMPORT, null); - } - - } - /** to use log facility, just put in your code: log.info(\"...\"); */ static private Log log = LogFactory.getLog(RegionImportJson.class); @@ -411,7 +97,7 @@ if (!isRegion) { // il n'y a qu'un objet dans le json, on le deserialize String rootId = info.get("rootId").asText(); - RegionVisitor v = new RegionVisitor(merge, rootId, entities, jsonEntities); + RegionVisitor v = new RegionVisitor(merge, null, null, rootId, entities, jsonEntities); // no assigment, collect of entities is done during deserialize v.loadEntity(); } else { @@ -422,7 +108,7 @@ // les champs commencant par des # sont #info et #entities if (!field.getKey().startsWith("#")) { for (JsonNode id : field.getValue()) { - RegionVisitor v = new RegionVisitor(merge, id.asText(), entities, jsonEntities); + RegionVisitor v = new RegionVisitor(merge, null, null, id.asText(), entities, jsonEntities); // no assigment, collect of entities is done during deserialize v.loadEntity(); } @@ -440,13 +126,19 @@ protected RegionMerge merge; protected JsonNode nodeEntity; + protected TopiaEntity parentEntity; + protected String propertyName; protected TopiaEntity currentEntity; protected LinkedHashMap<String, TopiaEntity> entities; protected JsonNode jsonEntities; - public RegionVisitor(RegionMerge merge, String idEntity, + public RegionVisitor(RegionMerge merge, + TopiaEntity parentEntity, String propertyName, + String idEntity, LinkedHashMap<String, TopiaEntity> entities, JsonNode jsonEntities) { this.merge = merge; + this.parentEntity = parentEntity; + this.propertyName = propertyName; this.nodeEntity = jsonEntities.get(idEntity); this.entities = entities; this.jsonEntities = jsonEntities; @@ -461,20 +153,19 @@ return currentEntity; } - protected TopiaEntity convertJsonToEntity(JsonNode node) { - TopiaEntity result; + protected TopiaEntity convertJsonToEntity(JsonNode node, TopiaEntity result) { String id = node.get("#id").asText(); String className = node.get("#class").asText(); try { // try to reuse entity - result = merge.getEntity(id); if (result == null) { - // if no entity with same id, create new one + // if no entity with same id, create new one, with new Id Class clazz = Class.forName(className); result = (TopiaEntity)clazz.newInstance(); - result.setTopiaId(id); + result.setTopiaId(TopiaId.create(TopiaId.getClassName(id))); } // add in list save after import + // id and result.id can be different. id is used to keep link in json entities.put(id, result); result.accept(this); @@ -497,7 +188,22 @@ TopiaEntity result; String toString = node.get("#toString").asText(); - RegionMerge.Answer answer = merge.choice(id, toString, details); + + EnumSet<RegionMerge.AnswerType> disallow = EnumSet.noneOf(RegionMerge.AnswerType.class); + + // specifique rule for some Entities + Class currentEntityClass = TopiaId.getClassName(id); + if (Species.class.isAssignableFrom(currentEntityClass) && Population.PROPERTY_SPECIES.equals(propertyName)) { + // une population a forcement une espece + disallow.add(RegionMerge.AnswerType.NONE); + } else if (Cell.class.isAssignableFrom(currentEntityClass)) { + // on ne peut pas importer une Cellule d'une autre Region + disallow.add(RegionMerge.AnswerType.CREATE); + } + + RegionMerge.Answer answer = merge.choice(id, toString, details, + disallow.toArray(new RegionMerge.AnswerType[disallow.size()])); + switch (answer.type) { case ABORT: throw new IsisFishRuntimeException("Import aborted by user"); @@ -504,17 +210,22 @@ case NONE: result = null; break; - case REUSE: + case USE: result = answer.entity; break; + case REPLACE: + result = convertJsonToEntity(node, answer.entity); + break; + case CREATE: + result = convertJsonToEntity(node, null); + break; default: - result = convertJsonToEntity(node); - break; + throw new IsisFishRuntimeException("Unsupported action"); } return result; } - protected Object readValue(Class<?> type, JsonNode value) { + protected Object readValue(final String propertyName, Class<?> type, JsonNode value) { Object result; try { if (value == null || value.isNull() || value.isMissingNode()) { @@ -521,7 +232,7 @@ result = null; } else if (TopiaEntity.class.isAssignableFrom(type)) { String id = value.asText(); - RegionVisitor child = new RegionVisitor(merge, id, entities, jsonEntities); + RegionVisitor child = new RegionVisitor(merge, currentEntity, propertyName, id, entities, jsonEntities); result = child.loadEntity(); } else if (MatrixND.class.isAssignableFrom(type)) { String mat = value.asText(); @@ -530,7 +241,7 @@ new EntitySemanticsDecorator.EntityProvider() { @Override public Object findById(String id) { - RegionVisitor child = new RegionVisitor(merge, id, entities, jsonEntities); + RegionVisitor child = new RegionVisitor(merge, currentEntity, propertyName, id, entities, jsonEntities); Object result = child.loadEntity(); return result; } @@ -579,7 +290,7 @@ public void visit(TopiaEntity entity, String propertyName, Class<?> type, Object value) { JsonNode jsonValue = nodeEntity.get(propertyName); try { - value = readValue(type, jsonValue); + value = readValue(propertyName, type, jsonValue); BeanUtils.setProperty(entity, propertyName, value); } catch (Exception eee) { throw new IsisFishRuntimeException(String.format("Can't set property '%s' from json value: '%s'", propertyName, jsonValue), eee); @@ -590,15 +301,15 @@ public void visit(TopiaEntity entity, String propertyName, Class<?> collectionType, Class<?> type, Object value) { JsonNode jsonValue = nodeEntity.get(propertyName); try { - if (value != null) { + if (jsonValue != null) { Collection c; if (Set.class.isAssignableFrom(collectionType)) { c = new HashSet(); } else { - c = new LinkedList(); + c = new ArrayList(); } for (JsonNode currentValue : jsonValue) { - Object v = readValue(type, currentValue); + Object v = readValue(propertyName, type, currentValue); if (v != null) { c.add(v); } @@ -619,4 +330,344 @@ public void clear() { } } + + /** + * Use during import to merge imported data in existing Region + */ + static public interface RegionMerge { + static public enum AutoAnswerType { + ONCE("Reply only for this awnser"), + TYPE("Reply all time same thing for this type"), + ALL("Reply all time same thing for all type"); + + private final String toString; + private AutoAnswerType(String toString) { + this.toString = toString; + } + + @Override + public String toString() { + return toString; + } + + } + + static public enum AnswerType { + NONE("None", "don't import nor reuse an object."), + USE("Use", "use (don't import) object already in current Region (make your choice in next combobox)."), + REPLACE("Replace", "replace object in current Region with imported object from file (make your choice in next combobox"), + CREATE("Create", "create new object from file."), + ABORT("Abort", "cancel this import (import nothing)."); + + private final String toString; + private final String description; + AnswerType(String toString, String description) { + this.toString = toString; + this.description = description; + } + + public String getDescription() { + return description; + } + + @Override + public String toString() { + return toString; + } + }; + + static public class Answer { + public AnswerType type; + public TopiaEntity entity; + + public Answer(AnswerType type, TopiaEntity entity) { + this.type = type; + this.entity = entity; + } + } + + /** + * Ask how to merge entity + * @param id + * @param toString + * @param details + * @param disallow + * @return + */ + public Answer choice(String id, String toString, Map<String, Object> details, AnswerType ... disallow); + + public boolean isAbort(); + } + + static public class RegionMergeDatabase implements RegionMerge { +// static public enum ComplexeAnswerType { +// NONE("None", "don't import nor reuse an object."), +// NONE_THIS_TYPE("None same type", "auto reply None for this answer and all next answer for same object type."), +// NONE_ALL("None all", "auto reply None for this answer and all next answer for all object type."), +// +// USE("Use", "use (don't import) object already in current Region (make your choice in next combobox)."), +// USE_THIS_TYPE("Use same type", "auto reply Use for this answer and all next answer if only one object found ('id' or 'name') in current Region for this type."), +// USE_ALL("Use all", "auto reply Use for this answer and all next answer if only one object found ('id' or 'name') in current Region for all object."), +// +// REPLACE("Replace", "replace object in current Region with imported object from file (make your choice in next combobox"), +// REPLACE_THIS_TYPE("Replace same type", "auto reply Replace for this answer and all next answer if only one object found ('id' or 'name') in current Region for this type."), +// REPLACE_ALL("Replace all", "auto reply Replace for this answer and all next answer if only one object found ('id' or 'name') in current Region for all object."), +// +// CREATE("Create", "create new object from file."), +// CREATE_THIS_TYPE("Create same type", "auto reply Create for this answer and all next answer for same object type."), +// CREATE_ALL("Create All", "auto reply Create for this answer and all next answer for all object."), +// +// ABORT("Abort", "cancel this import (import nothing)."); +// +// private final String toString; +// private final String description; +// ComplexeAnswerType(String toString, String description) { +// this.toString = toString; +// this.description = description; +// } +// +// public String getDescription() { +// return description; +// } +// +// @Override +// public String toString() { +// return toString; +// } +// } + + /** + * Object used to keep recurent answer (abort, import All, reuse All, ...) + */ + static public class RegionMergeContext { + protected boolean abort = false; + + protected EnumSet<AnswerType> replyAll = EnumSet.noneOf(AnswerType.class); + protected HashMap<AnswerType, Set<Class>> replyType = new HashMap<AnswerType, Set<Class>>() { + @Override + public Set<Class> get(Object key) { + Set<Class> result = super.get(key); + if (result == null) { + result = new HashSet<Class>(); + put((AnswerType)key, result); + } + return result; + } + }; +// protected boolean noneAll = false; +// protected Set<Class> noneType = new HashSet<Class>(); +// protected boolean useAll = false; +// protected Set<Class> useType = new HashSet<Class>(); +// protected boolean replaceAll = false; +// protected Set<Class> replaceType = new HashSet<Class>(); +// protected boolean createAll = false; +// protected Set<Class> createType = new HashSet<Class>(); + + protected AnswerType lastAnswerType = null; + protected TopiaEntity reuseEntity; + protected Class currentType; + + public RegionMergeContext() { + } + + public RegionMergeContext(boolean importAll) { + this.replyAll.add(AnswerType.CREATE); + } + + public RegionMerge.Answer getAnswer() { + RegionMerge.Answer result = null; + if (lastAnswerType != null) { + result = new RegionMerge.Answer(lastAnswerType, reuseEntity); + } + return result; + } + + public Class getCurrentType() { + return currentType; + } + + protected void setLastAnswer(AnswerType lastAnswer, AutoAnswerType autoType) { + this.setLastAnswer(lastAnswer, autoType, null); + } + + protected void setLastAnswer(AnswerType lastAnswer, AutoAnswerType autoType, TopiaEntity e) { + this.reuseEntity = e; + this.lastAnswerType = lastAnswer; + + if (AnswerType.ABORT == lastAnswer) { + abort = true; + } + + switch (autoType) { + case TYPE: + Set<Class> set = replyType.get(lastAnswer); + set.add(currentType); + break; + case ALL: + replyAll.add(lastAnswer); + break; + } + } + + public AnswerType initAnswer(Class type) { + lastAnswerType = null; + currentType = type; + if (abort) { + lastAnswerType = AnswerType.ABORT; + } else if (replyAll.contains(AnswerType.NONE) || replyType.get(AnswerType.NONE).contains(type)) { + lastAnswerType = AnswerType.NONE; + } else if (replyAll.contains(AnswerType.CREATE) || replyType.get(AnswerType.CREATE).contains(type)) { + lastAnswerType = AnswerType.CREATE; + } + return lastAnswerType; + } + + public AnswerType initAnswer(Class type, Set<TopiaEntity> possible) { + lastAnswerType = null; + currentType = type; + if (possible != null && possible.size() == 1 && + (replyAll.contains(AnswerType.USE) || replyType.get(AnswerType.USE).contains(type))) { + lastAnswerType = AnswerType.USE; + this.reuseEntity = possible.iterator().next(); + } else if (possible != null && possible.size() == 1 && + (replyAll.contains(AnswerType.REPLACE) || replyType.get(AnswerType.REPLACE).contains(type))) { + lastAnswerType = AnswerType.REPLACE; + this.reuseEntity = possible.iterator().next(); + } + return lastAnswerType; + } + } + + + protected TopiaContext tx; + protected RegionMergeContext context; + protected Answer lastAnswer; + + public RegionMergeDatabase(TopiaContext tx) { + this.tx = tx; + } + + protected boolean isAcceptableAnswer(AnswerType type, AnswerType ... disallow) { + boolean result = type != null && !Arrays.asList(disallow).contains(type); + return result; + } + + @Override + public Answer choice(String id, String toString, Map<String, Object> details, AnswerType ... disallow) { + Class type = TopiaId.getClassName(id); + if (context == null) { + context = new RegionMergeContext(); + } + + if (!isAcceptableAnswer(context.initAnswer(type), disallow)) { + TopiaDAO<TopiaEntity> dao = IsisFishDAOHelper.getDAO(tx, type); + + LinkedHashSet<TopiaEntity> possible = new LinkedHashSet<TopiaEntity>(); + + possible.add(dao.findByTopiaId(id)); + if (Equation.class.isAssignableFrom(context.getCurrentType())) { + if (details.containsKey("name") && details.containsKey("category")) { + possible.addAll(dao.findAllByProperties("name", details.get("name"), "category", details.get("category"))); + } + } else { + if (details.containsKey("name")) { + possible.addAll(dao.findAllByProperty("name", details.get("name"))); + } + } + + if (!isAcceptableAnswer(context.initAnswer(type, possible), disallow)) { + if (Equation.class.isAssignableFrom(context.getCurrentType())) { + if (details.containsKey("category")) { + possible.addAll(dao.findAllByProperty("category", details.get("category"))); + } + } else { + possible.addAll(dao.findAll()); + } + + ask(context, toString, details, possible, disallow); + } + } + + return lastAnswer = context.getAnswer(); + } + + protected AnswerType ask(RegionMergeContext context, String toString, + Map<String, Object> details, Collection<TopiaEntity> possible, + AnswerType ... disallow) { + + JPanel radioPanel = new JPanel(new GridLayout(1, 0)); + ButtonGroup group = new ButtonGroup(); + for (AutoAnswerType auto : AutoAnswerType.values()) { + JRadioButton radio = new JRadioButton(auto.toString); + radio.setSelected(AutoAnswerType.ONCE == auto); + radio.setActionCommand(auto.name()); + group.add(radio); + radioPanel.add(radio); + } + + JComboBox select = new JComboBox(possible.toArray()); + + ArrayList<AnswerType> allowedOptions = + new ArrayList<AnswerType>(Arrays.asList(AnswerType.values())); + for (AnswerType t : disallow) { + allowedOptions.remove(t); + } + Object[] options = allowedOptions.toArray(); + + List descriptions = new ArrayList(); + descriptions.add(String.format("You try to import '%s' (%s)", toString, + ClassUtils.getShortClassName(context.getCurrentType()))); + descriptions.add("Possible answer are:"); + for (AnswerType t : allowedOptions) { + descriptions.add(t.toString() + ": " + t.getDescription()); + } + descriptions.add(select); + // answer only for this answer + // make same answer for ask about same type + // make same answer all time + descriptions.add(radioPanel); + + int result = JOptionPane.showOptionDialog(null, + descriptions.toArray(), + "Make a choice", + JOptionPane.DEFAULT_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + options, + options[0]); + + TopiaEntity selectEntity = (TopiaEntity)select.getSelectedItem(); + if (result >= 0) { + AnswerType reply = allowedOptions.get(result); + AutoAnswerType auto = AutoAnswerType.valueOf(group.getSelection().getActionCommand()); + context.setLastAnswer(reply, auto, selectEntity); + } else { + ask(context, toString, details, possible); + } + return context.lastAnswerType; + } + + @Override + public boolean isAbort() { + boolean result = lastAnswer != null && lastAnswer.type == AnswerType.ABORT; + return result; + } + + } + + static public class RegionMergeImportAll implements RegionMerge { + protected Answer lastAnswer; + + @Override + public boolean isAbort() { + return false; + } + + @Override + public Answer choice(String id, String toString, Map<String, Object> details, AnswerType ... disallow) { + return lastAnswer = new Answer(AnswerType.CREATE, null); + } + + } + } Modified: trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputHandler.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputHandler.java 2016-11-23 13:08:32 UTC (rev 4374) +++ trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputHandler.java 2016-11-29 16:22:02 UTC (rev 4375) @@ -433,7 +433,8 @@ try { File file = FileUtil.getFile(".*\\.isonz$", t("isisfish.message.import.region.zipped")); - if (file != null) { + InputSaveVerifier inputSaveVerifier = inputUI.getContextValue(InputSaveVerifier.class); + if (file != null && inputSaveVerifier.checkEdit() != JOptionPane.CANCEL_OPTION) { FisheryRegion fisheryRegion = inputUI.getContextValue(FisheryRegion.class); TopiaContext tx = fisheryRegion.getTopiaContext(); RegionImportJson.RegionMergeDatabase merge = @@ -448,12 +449,17 @@ tx.add(e); } tx.commitTransaction(); + log.info("Import merged"); } catch (Exception eee) { tx.rollbackTransaction(); - if (!merge.getLastAnswer().isAbort()) { + if (!merge.isAbort()) { throw eee; + } else { + log.info("Import aborted"); } } + inputSaveVerifier.cancel(); + loadRegion(fisheryRegion.getName()); } } catch (Exception eee) { throw new IsisFishRuntimeException("Can't import region", eee); Modified: trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputSaveVerifier.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputSaveVerifier.java 2016-11-23 13:08:32 UTC (rev 4374) +++ trunk/src/main/java/fr/ifremer/isisfish/ui/input/InputSaveVerifier.java 2016-11-29 16:22:02 UTC (rev 4375) @@ -221,6 +221,9 @@ String typeSimpleName = type.getSimpleName(); String name = typeSimpleName + "_new"; + // FIXME 20161110 poussin don't use introspection but + // IsisFishDAOHelper.getDAO(context, type); + // use introspection to call IsisFishDAOHelper.getXXXDAO() TopiaContext topiaContext = inputContentUI.getTopiaContext(); Method method = MethodUtils.getAccessibleMethod(IsisFishDAOHelper.class,