Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe Commits: fb640b84 by Tony Chemit at 2020-12-03T20:17:25+01:00 Let's generate create actions (Open one are now ok, need to finish it for edit and table one) : generation is always better than runtime code... - - - - - 20 changed files: - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/ContentUIHandler.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/InsertMenuAction.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/table/actions/CreateNewContentTableUIEntry.java → client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/create/CreateNewContentTableUIEntry.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/open/actions/CreateNewOpenable.java → client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/create/CreateNewOpenableUI.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/mode/ChangeMode.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/mode/ChangeModeExecutor.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/edit/ContentEditUINavigationNode.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/list/ContentListUIHandler.java - − client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/list/actions/CreateNew.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/open/ContentOpenableUIHandler.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/tree/NavigationHandler.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/tree/NavigationNode.java - client/datasource/editor/ll/src/main/java/fr/ird/observe/client/datasource/editor/ll/data/LlTripActionHelper.java - client/datasource/editor/ll/src/main/java/fr/ird/observe/client/datasource/editor/ll/data/logbook/ActivitySampleUIMoveTreeAdapter.java - client/datasource/editor/ps/src/main/java/fr/ird/observe/client/datasource/editor/ps/data/PsTripActionHelper.java - client/datasource/editor/ps/src/main/java/fr/ird/observe/client/datasource/editor/ps/data/common/TripUIHandler.java - client/datasource/editor/ps/src/main/java/fr/ird/observe/client/datasource/editor/ps/data/observation/RouteUIHandler.java - client/datasource/editor/spi/src/main/java/fr/ird/observe/client/datasource/editor/spi/content/CapabilityDescriptor.java - client/datasource/editor/spi/src/main/java/fr/ird/observe/client/datasource/editor/spi/content/ContentNodeType.java - client/datasource/editor/spi/src/main/java/fr/ird/observe/client/datasource/editor/spi/content/helper/ContentUIHandlerHelper.java Changes: ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/ContentUIHandler.java ===================================== @@ -30,10 +30,10 @@ import fr.ird.observe.client.datasource.api.ObserveSwingDataSource; import fr.ird.observe.client.datasource.editor.api.DataSourceEditor; import fr.ird.observe.client.datasource.editor.api.content.actions.ContentUIActionSupport; import fr.ird.observe.client.datasource.editor.api.content.actions.ResetForm; +import fr.ird.observe.client.datasource.editor.api.content.actions.create.CreateNewContentTableUIEntry; import fr.ird.observe.client.datasource.editor.api.content.actions.open.ContentOpen; import fr.ird.observe.client.datasource.editor.api.content.data.table.ContentTableUI; import fr.ird.observe.client.datasource.editor.api.content.data.table.ContentTableUIModel; -import fr.ird.observe.client.datasource.editor.api.content.data.table.actions.CreateNewContentTableUIEntry; import fr.ird.observe.client.datasource.editor.api.content.referential.ContentReferentialUII18nHelper; import fr.ird.observe.client.datasource.editor.api.content.spi.ContentUIReferenceCache; import fr.ird.observe.client.datasource.editor.api.content.spi.ReferentialReferencesFilter; @@ -124,7 +124,7 @@ public abstract class ContentUIHandler<U extends ContentUI> implements ObserveSe private final Map<ContentTableUI<?, ?, ?>, JPanel> subUiMap = new LinkedHashMap<>(); protected String prefix; protected U ui; - protected ImmutableSet<CreateNewContentTableUIEntry<?, ?>> newContentTableUIEntries; + protected ImmutableSet<CreateNewContentTableUIEntry<?>> newContentTableUIEntries; private ObserveLayoutFocusTraversalPolicy<U> focusTraversalPolicy; private boolean init; private JTabbedPaneValidator tabbedPaneValidator; @@ -308,6 +308,18 @@ public abstract class ContentUIHandler<U extends ContentUI> implements ObserveSe installChangeModeAction(); NodeCapability<?> capability = ui.getModel().getSource().getCapability(); if (capability instanceof ContainerCapability) { +// newContentOpenableUIEntries = CreateNewOpenableUI.installOpenableCreateActions(ui, (ContainerCapability<?>) capability); +// if (newContentOpenableUIEntries != null) { +// getModel().getStates().addPropertyChangeListener(evt -> { +// String propertyName = evt.getPropertyName(); +// if (propertyName.equals(ContentUIModelStates.PROPERTY_UPDATING_MODE) || +// propertyName.equals(ContentUIModelStates.PROPERTY_MODIFIED)) { +// ContentUIModelStates source = (ContentUIModelStates) evt.getSource(); +// boolean enabled = source.isUpdatingMode() && !source.isModified(); +// source.firePropertyChange(CreateNewOpenableUI.PROPERTY_NAME_UPDATING_MODE_AND_NOT_MODIFIED, enabled); +// } +// }); +// } newContentTableUIEntries = CreateNewContentTableUIEntry.installTableCreateActions(ui, (ContainerCapability<?>) capability); if (newContentTableUIEntries != null) { getModel().getStates().addPropertyChangeListener(evt -> { @@ -320,6 +332,7 @@ public abstract class ContentUIHandler<U extends ContentUI> implements ObserveSe } }); } + } // if (ui.getConfigurePopup().getSubElements().length == 0) { // ui.getToggleConfigure().setEnabled(false); ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/InsertMenuAction.java ===================================== @@ -34,6 +34,7 @@ import javax.swing.JPopupMenu; * @since 8.0.1 */ public interface InsertMenuAction<U extends ContentUI> extends MenuAction { + String PROPERTY_NAME_UPDATING_MODE_AND_NOT_MODIFIED = "updatingModeAndNotModified"; U getUi(); ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/table/actions/CreateNewContentTableUIEntry.java → client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/create/CreateNewContentTableUIEntry.java ===================================== @@ -1,4 +1,4 @@ -package fr.ird.observe.client.datasource.editor.api.content.data.table.actions; +package fr.ird.observe.client.datasource.editor.api.content.actions.create; /*- * #%L @@ -47,26 +47,26 @@ import java.awt.event.ActionEvent; import java.util.function.Function; /** - * To create a new entry from the outised world. + * To create a new table data entry from the outside world. * <p> * Created on 26/11/2020. * * @author Tony Chemit - dev@tchemit.fr * @since 8.0.1 */ -public class CreateNewContentTableUIEntry<N extends ContentTableUINavigationNode, U extends ContentUI> extends ContentUIActionSupport<U> implements InsertMenuAction<U> { - public static final String PROPERTY_NAME_UPDATING_MODE_AND_NOT_MODIFIED = "updatingModeAndNotModified"; +public class CreateNewContentTableUIEntry<U extends ContentUI> extends ContentUIActionSupport<U> implements InsertMenuAction<U> { + private static final Logger log = LogManager.getLogger(CreateNewContentTableUIEntry.class); - private final Function<NavigationNode, N> getNode; + private final Function<NavigationNode, NavigationNode> getNode; - public static <N extends ContentTableUINavigationNode, U extends ContentUI> CreateNewContentTableUIEntry<N, U> installAction(U ui, AbstractButton editor, SimpleDtoServiceContext<?, ?> spi, Function<NavigationNode, N> getNode) { - CreateNewContentTableUIEntry<N, U> action = new CreateNewContentTableUIEntry<>(spi, getNode); + public static <U extends ContentUI> CreateNewContentTableUIEntry<U> installAction(U ui, AbstractButton editor, SimpleDtoServiceContext<?, ?> spi, Function<NavigationNode, NavigationNode> getNode) { + CreateNewContentTableUIEntry<U> action = new CreateNewContentTableUIEntry<>(spi, getNode); init(ui, editor, action); return action; } - public static ImmutableSet<CreateNewContentTableUIEntry<?, ?>> installTableCreateActions(ContentUI ui, ContainerCapability<?> capability) { - ImmutableSet.Builder<CreateNewContentTableUIEntry<?, ?>> builder = ImmutableSet.builder(); + public static ImmutableSet<CreateNewContentTableUIEntry<?>> installTableCreateActions(ContentUI ui, ContainerCapability<?> capability) { + ImmutableSet.Builder<CreateNewContentTableUIEntry<?>> builder = ImmutableSet.builder(); for (Class<? extends NavigationNode> acceptedNodeType : capability.getAcceptedNodeTypes()) { if (ContentTableUINavigationNode.class.isAssignableFrom(acceptedNodeType)) { @SuppressWarnings("unchecked") Class<? extends ContentTableUINavigationNode> nodeType = (Class<? extends ContentTableUINavigationNode>) acceptedNodeType; @@ -85,7 +85,7 @@ public class CreateNewContentTableUIEntry<N extends ContentTableUINavigationNode return builder.build(); } - public CreateNewContentTableUIEntry(SimpleDtoServiceContext<?, ?> spi, Function<NavigationNode, N> getNode) { + public CreateNewContentTableUIEntry(SimpleDtoServiceContext<?, ?> spi, Function<NavigationNode, NavigationNode> getNode) { super(null, null, "add", null); this.getNode = getNode; Class<? extends DataDto> dtoType = spi.getDtoType(); @@ -97,7 +97,7 @@ public class CreateNewContentTableUIEntry<N extends ContentTableUINavigationNode @Override protected void doActionPerformed(ActionEvent e, U ui) { NavigationTree tree = getDataSourceEditor().getNavigationUI().getTree(); - N selectedNode = getNode.apply(tree.getSelectedNode()); + NavigationNode selectedNode = getNode.apply(tree.getSelectedNode()); tree.selectSafeNode(selectedNode); ContentTableUI<?, ?, ?> newContentUI = (ContentTableUI<?, ?, ?>) getDataSourceEditor().getContentUIManager().getSelectedContentUI(); newContentUI.getNewEntry().doClick(); ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/open/actions/CreateNewOpenable.java → client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/create/CreateNewOpenableUI.java ===================================== @@ -1,4 +1,4 @@ -package fr.ird.observe.client.datasource.editor.api.content.data.open.actions; +package fr.ird.observe.client.datasource.editor.api.content.actions.create; /*- * #%L @@ -22,16 +22,24 @@ package fr.ird.observe.client.datasource.editor.api.content.data.open.actions; * #L% */ +import com.google.common.collect.ImmutableSet; import fr.ird.observe.client.datasource.editor.api.DataSourceEditor; +import fr.ird.observe.client.datasource.editor.api.content.ContentUI; +import fr.ird.observe.client.datasource.editor.api.content.actions.ContentUIActionSupport; import fr.ird.observe.client.datasource.editor.api.content.actions.InsertMenuAction; import fr.ird.observe.client.datasource.editor.api.content.actions.mode.ChangeMode; +import fr.ird.observe.client.datasource.editor.api.content.data.list.ContentListUI; import fr.ird.observe.client.datasource.editor.api.content.data.list.ContentListUII18nHelper; import fr.ird.observe.client.datasource.editor.api.content.data.list.ContentListUINavigationNode; import fr.ird.observe.client.datasource.editor.api.content.data.open.ContentOpenableUI; import fr.ird.observe.client.datasource.editor.api.navigation.NavigationTree; import fr.ird.observe.client.datasource.editor.api.navigation.tree.NavigationNode; +import fr.ird.observe.client.datasource.editor.api.navigation.tree.NavigationScope; +import fr.ird.observe.client.datasource.editor.api.navigation.tree.NavigationScopes; +import fr.ird.observe.client.datasource.editor.api.navigation.tree.capability.ContainerCapability; import fr.ird.observe.client.datasource.editor.api.navigation.tree.capability.ReferenceContainerCapability; import fr.ird.observe.client.util.DtoIconHelper; +import fr.ird.observe.dto.IdDto; import fr.ird.observe.dto.data.DataDto; import fr.ird.observe.dto.reference.DataDtoReference; import fr.ird.observe.spi.context.OpenableDtoServiceContext; @@ -41,30 +49,86 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import javax.swing.AbstractButton; +import javax.swing.JMenuItem; import java.awt.event.ActionEvent; -import java.util.Objects; import java.util.function.Function; +import java.util.function.Predicate; /** - * Created on 11/11/16. + * To create a new openable data from the outside world. + * Created on 03/12/2020. * * @author Tony Chemit - dev@tchemit.fr - * @since 6.0 + * @since 8.0.1 */ -public final class CreateNewOpenable<R extends DataDtoReference, D extends DataDto, U extends ContentOpenableUI<D, U>> extends ContentOpenableUIActionSupport<D, U> implements InsertMenuAction<U> { +public class CreateNewOpenableUI<D extends DataDto, U extends ContentUI> extends ContentUIActionSupport<U> implements InsertMenuAction<U> { - private static final Logger log = LogManager.getLogger(CreateNewOpenable.class); + private static final Logger log = LogManager.getLogger(CreateNewOpenableUI.class); + private final OpenableDtoServiceContext<D, ?, ?> spi; + private final Function<NavigationNode, NavigationNode> getNode; + private final Predicate<Class<D>> typePredicate; - private final OpenableDtoServiceContext<?, R, ?> spi; - private final Function<NavigationNode, NavigationNode> beforeNodeFunction; + public static ImmutableSet<CreateNewOpenableUI<?, ?>> installOpenableCreateActions(ContentUI ui, ContainerCapability<?> capability) { + ImmutableSet.Builder<CreateNewOpenableUI<?, ?>> builder = ImmutableSet.builder(); + for (Class<? extends NavigationNode> acceptedNodeType : capability.getAcceptedNodeTypes()) { + if (ContentListUINavigationNode.class.isAssignableFrom(acceptedNodeType)) { + JMenuItem editor = new JMenuItem(); + NavigationScope navigationScope = NavigationScopes.getNavigationScope(acceptedNodeType); + @SuppressWarnings("unchecked") Class<? extends ContentListUINavigationNode> nodeType = (Class<? extends ContentListUINavigationNode>) acceptedNodeType; + OpenableDtoServiceContext<?, ?, ?> spi = navigationScope.computeOpenSpi(); + String fieldName = "add" + acceptedNodeType.getSimpleName().replace("UINavigationNode", ""); + editor.setName(fieldName); + ui.getModel().getStates().addPropertyChangeListener(PROPERTY_NAME_UPDATING_MODE_AND_NOT_MODIFIED, evt -> editor.setEnabled((Boolean) evt.getNewValue())); + log.debug("Create new action: " + fieldName); + ui.get$objectMap().put(editor.getName(), editor); + Function<NavigationNode, NavigationNode> getNode = n -> n.findChildByType(nodeType); + builder.add(installAction(ui, editor, spi, getNode)); + } + } + return builder.build(); + } + + public static <D extends DataDto, U extends ContentOpenableUI< ?, ?>> CreateNewOpenableUI<D, U> installAction2(U ui, Class<? extends NavigationNode> acceptedNodeType, Class<D> dtoType, Predicate<Class<D>> typePredicate) { + JMenuItem editor = new JMenuItem(); + NavigationScope navigationScope = NavigationScopes.getNavigationScope(acceptedNodeType); + @SuppressWarnings("unchecked") Class<? extends ContentListUINavigationNode> nodeType = (Class<? extends ContentListUINavigationNode>) acceptedNodeType; + OpenableDtoServiceContext<D, ?, ?> spi = navigationScope.computeOpenSpi(); + String fieldName = "add" + acceptedNodeType.getSimpleName().replace("UINavigationNode", ""); + editor.setName(fieldName); + ui.getModel().getStates().addPropertyChangeListener(PROPERTY_NAME_UPDATING_MODE_AND_NOT_MODIFIED, evt -> editor.setEnabled((Boolean) evt.getNewValue())); + log.debug("Create new action: " + fieldName); + ui.get$objectMap().put(editor.getName(), editor); + Function<NavigationNode, NavigationNode> getNode = n -> n.findChildByType(nodeType); + + CreateNewOpenableUI<D, U> action = new CreateNewOpenableUI<>(spi, getNode, typePredicate); + init(ui, ui.getCreate(), action); + return action; + } + + public static <D extends DataDto, U extends ContentListUI<?, ?, ?>> CreateNewOpenableUI<D, U> installAction(U ui, Predicate<Class<D>> typePredicate) { + CreateNewOpenableUI<D, U> action = new CreateNewOpenableUI<>(ui.getModel().getScope().computeOpenSpi(), Function.identity(), typePredicate); + init(ui, ui.getCreate(), action); + return action; + } - public static <D extends DataDto, U extends ContentOpenableUI<D, U>> void installAction(U ui) { - installAction(ui, ui.getCreate(), ui.getModel().getSource().getSpi(), t -> t); + public static <D extends DataDto, U extends ContentOpenableUI<D, U>> CreateNewOpenableUI<D, U> installAction(U ui, Predicate<Class<D>> typePredicate) { + CreateNewOpenableUI<D, U> action = new CreateNewOpenableUI<>(ui.getModel().getScope().computeOpenSpi(), Function.identity(), typePredicate); + init(ui, ui.getCreate(), action); + return action; } - public static <R extends DataDtoReference, D extends DataDto, U extends ContentOpenableUI<D, U>> void installAction(U ui, AbstractButton editor, OpenableDtoServiceContext<?, R, ?> spi, Function<NavigationNode, NavigationNode> beforeNodeFunction) { - CreateNewOpenable<R, D, U> action = new CreateNewOpenable<>(ui.getModel().getSource().getScope().getMainType(), spi, beforeNodeFunction); + public static <D extends DataDto, U extends ContentOpenableUI<D, U>> CreateNewOpenableUI<D, U> installAction(U ui) { + return installAction(ui, t -> true); + } + + public static <D extends DataDto, U extends ContentListUI<?, ?, ?>> CreateNewOpenableUI<D, U> installAction(U ui) { + return installAction(ui, t -> true); + } + + public static <D extends DataDto, U extends ContentUI> CreateNewOpenableUI<D, U> installAction(U ui, AbstractButton editor, OpenableDtoServiceContext<D, ?, ?> spi, Function<NavigationNode, NavigationNode> getNode) { + CreateNewOpenableUI<D, U> action = new CreateNewOpenableUI<>(spi, getNode, t -> true); init(ui, editor, action); + return action; } public static void closeAndCreate(DataSourceEditor dataSourceEditor, NavigationNode parentNode, NavigationTree tree, EditNode<?> editNode, DataDtoReference reference) { @@ -79,24 +143,28 @@ public final class CreateNewOpenable<R extends DataDtoReference, D extends DataD } } - public CreateNewOpenable(Class<D> dataType, OpenableDtoServiceContext<?, R, ?> spi, Function<NavigationNode, NavigationNode> beforeNodeFunction) { - super(dataType, null, null, null, null); - this.spi = Objects.requireNonNull(spi); - this.beforeNodeFunction = Objects.requireNonNull(beforeNodeFunction); + public CreateNewOpenableUI(OpenableDtoServiceContext<D, ?, ?> spi, Function<NavigationNode, NavigationNode> getNode, Predicate<Class<D>> typePredicate) { + super(null, null, "add", null); + this.spi = spi; + this.getNode = getNode; + this.typePredicate = typePredicate; Class<? extends DataDto> dtoType = spi.getDtoType(); setIcon(DtoIconHelper.getIcon(dtoType)); setText(ContentListUII18nHelper.getListActionCreate(dtoType)); - setTooltipText(ContentListUII18nHelper.getListActionCreateTip(dtoType)); + setTooltipText(ContentListUII18nHelper.getListActionCreate(dtoType)); } @Override - protected void doActionPerformed(ActionEvent event, U ui) { - NavigationTree tree = getDataSourceEditor().getNavigationUI().getTree(); - NavigationNode selectedNode = beforeNodeFunction.apply(tree.getSelectedNode()); - Class<? extends DataDtoReference> referenceType = selectedNode.getScope().getMainReferenceType(); - ContentListUINavigationNode parentNode = (ContentListUINavigationNode) selectedNode.upToReferenceContainerNode(referenceType); - DataDtoReference newReference = spi.newReference(ui.getModel().getClientUIContext().getDecoratorService().getReferentialLocale()); - closeAndCreate(getDataSourceEditor(), parentNode, tree, selectedNode.getInitializer().getEditNode(), newReference); + protected boolean canExecuteAction(ActionEvent e) { + return super.canExecuteAction(e) && (typePredicate == null || typePredicate.test(spi.getDtoType())); } + @Override + protected void doActionPerformed(ActionEvent e, U ui) { + NavigationTree tree = getDataSourceEditor().getNavigationUI().getTree(); + NavigationNode parentNode = getNode.apply(tree.getSelectedNode()); + EditNode<? extends IdDto> editNode = parentNode.getInitializer().getEditNode(); + DataDtoReference newReference = spi.newReference(parentNode.getInitializer().getReferentialLocale()); + closeAndCreate(getDataSourceEditor(), parentNode, tree, editNode, newReference); + } } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/mode/ChangeMode.java ===================================== @@ -79,7 +79,7 @@ public class ChangeMode<U extends ContentUI> extends ContentUIActionSupport<U> { } public static void closeData(DataSourceEditor dataSourceEditor, EditNode<?> nodeToClose) throws CloseEditNodeVetoException { - if (nodeToClose.isDisabled()) { + if (Objects.requireNonNull(nodeToClose).isDisabled()) { return; } ClientUIContext clientUIContext = ClientUIContextApplicationComponent.value(); ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/mode/ChangeModeExecutor.java ===================================== @@ -57,62 +57,45 @@ public class ChangeModeExecutor<U extends ContentUI> { protected void doClose(U ui, DataSourceEditor dataSourceEditor, ChangeModeRequest request) { try { - EditNode<?> editNode = ui.getModel().getSource().getInitializer().getEditNode(); + SelectNode<?> selectedNode = request.getSelectNode(ui); + EditNode<?> editNode = request.getEditNode(ui); + String id = request.getSelectedId(ui, selectedNode); + log.info(String.format("Will close: %s → (select: %s - edit: %s)", id, selectedNode, editNode)); ChangeMode.closeData(dataSourceEditor, editNode); if (ui.getModel().getStates().isUpdatingMode()) { ui.stopEdit(); } afterClose(ui, dataSourceEditor); - //FIXME See what does it means ? -// getMainUI().getHandler().updateContentSize(); } catch (CloseEditNodeVetoException e1) { log.error("Could not close data from callback", e1); -// UIHelper.handlingError(e1); } } protected void doOpen(U ui, DataSourceEditor dataSourceEditor, ChangeModeRequest request) { - - SelectNode<?> selectedNode = request.getSelectNode(ui); - EditNode<?> editNode = request.getEditNode(ui); - String id = request.getSelectedId(ui, selectedNode); - log.info(String.format("Will open: %s → %s", id, selectedNode)); - NavigationTree tree = dataSourceEditor.getNavigationUI().getTree(); - NavigationNode previousOpenedNode = editNode.isEnabled() ? tree.getRootNode().findNode(editNode) : null; try { + SelectNode<?> selectedNode = request.getSelectNode(ui); + EditNode<?> editNode = request.getEditNode(ui); + String id = request.getSelectedId(ui, selectedNode); + log.info(String.format("Will open: %s → (select: %s - edit: %s)", id, selectedNode, editNode)); + NavigationTree tree = dataSourceEditor.getNavigationUI().getTree(); + NavigationNode previousOpenedNode = editNode.isEnabled() ? tree.getRootNode().findNode(editNode) : null; ChangeMode.openData(editNode, selectedNode, id); afterOpen(dataSourceEditor, previousOpenedNode, id); } catch (CloseEditNodeVetoException e1) { log.error("Could not close data from callback", e1); - //UIHelper.handlingError(e1); } } protected void afterClose(U ui, DataSourceEditor dataSourceEditor) { - -// ContentOpenableUIModel<D> model = ui.getModel(); -// D bean = model.getStates().getBean(); - ui.stopEdit(); - -// model.setMode(ContentMode.READ); -// removeAllMessages(ui); -// String closeMessage = ContentOpenableUII18nHelper.getMessageNotOpen(model.getScope().getMainType()); -// ContentUIHandler.addMessage(ui, NuitonValidatorScope.INFO, ContentOpenableUII18nHelper.getType(bean.getClass()), closeMessage); - NavigationTree tree = dataSourceEditor.getNavigationUI().getTree(); - NavigationNode node = tree.getSelectedNode(); node.getParent().refreshToRoot(); node.nodeChangedDeep(); -// if (node.getLevel() > 1) { -// tree.selectSafeNode(node.getParent()); -// } + log.info("Will reselect node: " + node); SwingUtilities.invokeLater(() -> tree.reSelectSafeNode(node)); -// ui.getHandler().updateActions(); - //FIXME Focus forcing!!! // ui.getHandler().grabFocusOnForm(); @@ -120,12 +103,6 @@ public class ChangeModeExecutor<U extends ContentUI> { protected void afterOpen(DataSourceEditor dataSourceEditor, NavigationNode previousOpenedNode, String id) { -// ui.stopEdit(); -// ui.getModel().setMode(ContentMode.UPDATE); -// -// // On charge les ensembles de références utilisées dans les combobox -// ui.getModel().updateUiWithReferenceSetsFromModel(); - // on repaint le parent (le program devient alors ouvert) NavigationTree tree = dataSourceEditor.getNavigationUI().getTree(); @@ -137,19 +114,12 @@ public class ChangeModeExecutor<U extends ContentUI> { if (previousOpenedNode == null || !Objects.equals(previousOpenedNode.getParent(), selectedNode.getParent())) { selectedNode.getParent().refreshToRoot(); } + selectedNode.reloadNodeData(); selectedNode.nodeChangedDeep(); -// if (selectedNode.getLevel() > 1) { -// tree.selectSafeNode(selectedNode.getParent()); -// } - afterOpenReselectNode(tree, id); -// ContentUIHandler.removeAllMessages(ui); -// -// // on lance l'édition -// ui.startEdit(); + afterOpenReselectNode(tree, selectedNode, id); } - protected void afterOpenReselectNode(NavigationTree tree, String id) { - NavigationNode selectedNode = tree.getSelectedNode(); + protected void afterOpenReselectNode(NavigationTree tree, NavigationNode selectedNode, String id) { log.info("Will reselect node: " + selectedNode); SwingUtilities.invokeLater(() -> tree.reSelectSafeNode(selectedNode)); } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/edit/ContentEditUINavigationNode.java ===================================== @@ -90,12 +90,14 @@ public abstract class ContentEditUINavigationNode extends NavigationNode { if (notPersisted) { getInitializer().updateSelectNodeId(id); } - if (notPersisted) { + // reload node data first + reloadNodeData(); + + if (notPersisted && isContainer()) { + // can now load children if any dirty(); populateChildrenIfNotLoaded(); } - // reload node data - reloadNodeData(); ReferenceContainerCapability<?> capability = (ReferenceContainerCapability<?>) parent.getCapability(); int newPosition = capability.getNodePosition(reference); ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/list/ContentListUIHandler.java ===================================== @@ -125,8 +125,7 @@ public abstract class ContentListUIHandler<D extends DataDto, R extends DataDtoR ChangeModeRequest request = ui.getModel().toChangeModeRequest(); ChangeModeExecutor<U> executor = new ChangeModeExecutor<U>() { @Override - protected void afterOpenReselectNode(NavigationTree tree, String id) { - NavigationNode selectedNode = tree.getSelectedNode(); + protected void afterOpenReselectNode(NavigationTree tree, NavigationNode selectedNode, String id) { Class<? extends DataDtoReference> referenceType = ui.getModel().getSource().getScope().getMainReferenceType(); NavigationNode referenceNode = tree.getSelectedNode().downToReferenceNode(referenceType, id); log.info(String.format("Will reselect node: %s", selectedNode)); ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/list/actions/CreateNew.java deleted ===================================== @@ -1,80 +0,0 @@ -package fr.ird.observe.client.datasource.editor.api.content.data.list.actions; - -/*- - * #%L - * ObServe Client :: DataSource :: Editor :: API - * %% - * Copyright (C) 2008 - 2020 IRD, Code Lutin, Ultreia.io - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import fr.ird.observe.client.datasource.editor.api.content.actions.InsertMenuAction; -import fr.ird.observe.client.datasource.editor.api.content.data.list.ContentListUI; -import fr.ird.observe.client.datasource.editor.api.content.data.list.ContentListUII18nHelper; -import fr.ird.observe.client.datasource.editor.api.content.data.list.ContentListUIModel; -import fr.ird.observe.client.datasource.editor.api.content.data.list.ContentListUINavigationNode; -import fr.ird.observe.client.datasource.editor.api.content.data.open.actions.CreateNewOpenable; -import fr.ird.observe.client.datasource.editor.api.navigation.NavigationTree; -import fr.ird.observe.client.util.DtoIconHelper; -import fr.ird.observe.dto.data.DataDto; -import fr.ird.observe.dto.reference.DataDtoReference; - -import java.awt.event.ActionEvent; -import java.util.Objects; -import java.util.function.Predicate; - -/** - * Created on 11/11/16. - * - * @author Tony Chemit - dev@tchemit.fr - * @since 6.0 - */ -public final class CreateNew<D extends DataDto, R extends DataDtoReference, U extends ContentListUI<D, R, U>> extends ContentListUIActionSupport<D, R, U> implements InsertMenuAction<U> { - - private final Predicate<Class<D>> typePredicate; - - public static <D extends DataDto, R extends DataDtoReference, U extends ContentListUI<D, R, U>> void installAction(U ui) { - installAction(ui, t -> true); - } - - public static <D extends DataDto, R extends DataDtoReference, U extends ContentListUI<D, R, U>> void installAction(U ui, Predicate<Class<D>> typePredicate) { - CreateNew<D, R, U> action = new CreateNew<>(ui.getModel().getSource().getScope().getMainType(), typePredicate); - init(ui, Objects.requireNonNull(ui).getCreate(), action); - } - - protected CreateNew(Class<D> dataType, Predicate<Class<D>> typePredicate) { - super(dataType, null, null, "add", null); - this.typePredicate = typePredicate; - setText(ContentListUII18nHelper.getListActionCreate(dataType)); - setTooltipText(ContentListUII18nHelper.getListActionCreateTip(dataType)); - setIcon(DtoIconHelper.getIcon(dataType)); - } - - @Override - protected boolean canExecuteAction(ActionEvent e) { - return super.canExecuteAction(e) && (typePredicate == null || typePredicate.test(getDataType())); - } - - @Override - protected void doActionPerformed(ActionEvent e, U ui) { - NavigationTree tree = getDataSourceEditor().getNavigationUI().getTree(); - ContentListUIModel<D, R> model = ui.getModel(); - ContentListUINavigationNode parentNode = (ContentListUINavigationNode) tree.getSelectedNode(); - DataDtoReference newReference = parentNode.getSpi().newReference(parentNode.getInitializer().getReferentialLocale()); - CreateNewOpenable.closeAndCreate(getDataSourceEditor(), parentNode, tree, model.getSource().getInitializer().getEditNode(), newReference); - } -} ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/open/ContentOpenableUIHandler.java ===================================== @@ -26,7 +26,6 @@ import fr.ird.observe.client.datasource.editor.api.content.actions.ResetForm; import fr.ird.observe.client.datasource.editor.api.content.actions.id.ShowTechnicalInformations; import fr.ird.observe.client.datasource.editor.api.content.actions.mode.ChangeMode; import fr.ird.observe.client.datasource.editor.api.content.actions.open.ContentOpen; -import fr.ird.observe.client.datasource.editor.api.content.data.open.actions.CreateNewOpenable; import fr.ird.observe.client.datasource.editor.api.content.data.open.actions.DeleteOpenable; import fr.ird.observe.client.datasource.editor.api.content.data.open.actions.SaveOpenable; import fr.ird.observe.dto.data.DataDto; @@ -40,6 +39,8 @@ public abstract class ContentOpenableUIHandler<D extends DataDto, U extends Cont protected abstract void installMoveAction(); + protected abstract void installCreateNewAction(); + @Override public ContentOpenableUIModel<D> getModel() { return ui.getModel(); @@ -62,7 +63,7 @@ public abstract class ContentOpenableUIHandler<D extends DataDto, U extends Cont @Override protected void initActions() { - installCreateAction(); + installCreateNewAction(); installResetAction(); installSaveAction(); installMoveAction(); @@ -75,10 +76,6 @@ public abstract class ContentOpenableUIHandler<D extends DataDto, U extends Cont ChangeMode.installAction(ui); } - protected void installCreateAction() { - CreateNewOpenable.installAction(ui); - } - protected void installSaveAction() { SaveOpenable.installAction(ui); } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/tree/NavigationHandler.java ===================================== @@ -86,17 +86,26 @@ public abstract class NavigationHandler<N extends NavigationNode> { return getIcon(getNode().getScope().isSubNode()); } + /** + * @return {@code true} if this node can build some children + */ public boolean canBuildChildren() { - return getNode().isNotLoaded() && getNode().isContainer(); + return getNode().isContainer(); } + /** + * @return {@code true} if this node can load his children while opening + */ public boolean canLoadChildrenOnOpen() { - // by default no sub loading - return getNode().isContainer() && getNode().getRoot().getHandler().canLoadChildrenOnOpen(); + // by default no sub loading except if loadChildrenOnOpen configuration property is on + return canBuildChildren() && getNode().getRoot().getHandler().canLoadChildrenOnOpen(); } public void open() { N node = getNode(); + // We can't predicate if structure was modified, so let's always refresh internal states + //FIXME Find a way to make this more smooth (listen datasource modification API (to create!!!)) + node.dirtyStructure(); node.getContext().open(); if (node.isLoaded()) { // already loaded, nothing more to do @@ -107,7 +116,7 @@ public abstract class NavigationHandler<N extends NavigationNode> { } node.loaded(); - if (canLoadChildrenOnOpen()) { + if (node.isRoot() || canLoadChildrenOnOpen()) { Enumeration<?> children = getNode().children(); while (children.hasMoreElements()) { NavigationNode childrenNode = (NavigationNode) children.nextElement(); @@ -126,13 +135,6 @@ public abstract class NavigationHandler<N extends NavigationNode> { return getNode().getChildCount(); } -// public void init() { - // nothing to do by default -// if (getNode().getScope().isAutoLoad()) { -// getNode().loaded(); -// } -// } - public final Icon getIcon(boolean small) { String iconPath = getNode().getScope().getIconPath(); return DtoIconHelper.getIcon(Objects.requireNonNull(iconPath), small); ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/tree/NavigationNode.java ===================================== @@ -180,8 +180,16 @@ public abstract class NavigationNode extends DefaultMutableTreeNode implements W } public final void dirty() { + if (isNotLoaded()) { + // Avoid re-entrant code + return; + } loaded = false; log.info(String.format("%s Make dirty node %s", getInitializer().getLogPrefix(), this)); + dirtyStructure(); + } + + public void dirtyStructure() { withPrevious.clear(); withNext.clear(); previous.clear(); @@ -189,6 +197,10 @@ public abstract class NavigationNode extends DefaultMutableTreeNode implements W } public final void loaded() { + if (isLoaded()) { + // Avoid re-entrant code + return; + } loaded = true; // when node is loaded, refresh ui getTreeModel().ifPresent(t -> nodeChanged()); @@ -309,6 +321,7 @@ public abstract class NavigationNode extends DefaultMutableTreeNode implements W } public final void reloadNodeData() { + dirty(); Object userObject = getContext().reload(); setUserObject(userObject); loaded(); @@ -327,9 +340,9 @@ public abstract class NavigationNode extends DefaultMutableTreeNode implements W //-------------------------------------------------------------------------------------------- public final void updateNode() { - dirty(); reloadNodeData(); removeAllChildren(); + dirty(); populateChildrenIfNotLoaded(); loaded(); } @@ -366,22 +379,6 @@ public abstract class NavigationNode extends DefaultMutableTreeNode implements W } } - //-------------------------------------------------------------------------------------------- - // Modify structure methods - //-------------------------------------------------------------------------------------------- - - public boolean isAdjusting() { - return adjusting; - } - - public void adjusting() { - this.adjusting = true; - } - - public void unAdjusting() { - this.adjusting = false; - } - public final void refreshToRoot() { if (!isRoot()) { log.info(String.format("Refresh to Root node: %s", this)); @@ -398,6 +395,22 @@ public abstract class NavigationNode extends DefaultMutableTreeNode implements W } } + //-------------------------------------------------------------------------------------------- + // Modify structure methods + //-------------------------------------------------------------------------------------------- + + public boolean isAdjusting() { + return adjusting; + } + + public void adjusting() { + this.adjusting = true; + } + + public void unAdjusting() { + this.adjusting = false; + } + @Override public void insert(MutableTreeNode newChild, int childIndex) { Optional<NavigationTreeModel> treeModel = getTreeModel(); ===================================== client/datasource/editor/ll/src/main/java/fr/ird/observe/client/datasource/editor/ll/data/LlTripActionHelper.java ===================================== @@ -24,7 +24,6 @@ package fr.ird.observe.client.datasource.editor.ll.data; import fr.ird.observe.client.datasource.editor.api.content.ContentUI; import fr.ird.observe.client.datasource.editor.api.content.data.TripActionHelper; -import fr.ird.observe.client.datasource.editor.api.content.data.list.ContentListUI; import fr.ird.observe.dto.data.DataDto; import fr.ird.observe.dto.data.ll.common.TripReference; @@ -38,15 +37,15 @@ import java.util.function.Predicate; */ public class LlTripActionHelper extends TripActionHelper { - public static <D extends DataDto> Predicate<Class<D>> createNewLandingActionPredicate(ContentListUI<D, ?, ?> ui) { + public static <D extends DataDto> Predicate<Class<D>> createNewLandingActionPredicate(ContentUI ui) { return (Class<D> r) -> new LlTripActionHelper(ui).gotoTripLogbookTab(); } - public static <D extends DataDto> Predicate<Class<D>> createNewLogbookActionPredicate(ContentListUI<D, ?, ?> ui) { + public static <D extends DataDto> Predicate<Class<D>> createNewLogbookActionPredicate(ContentUI ui) { return (Class<D> r) -> new LlTripActionHelper(ui).gotoTripLogbookTab(); } - public static <D extends DataDto> Predicate<Class<D>> createNewObservationActionPredicate(ContentListUI<D, ?, ?> ui) { + public static <D extends DataDto> Predicate<Class<D>> createNewObservationActionPredicate(ContentUI ui) { return (Class<D> r) -> new LlTripActionHelper(ui).gotoTripObservationTab(); } ===================================== client/datasource/editor/ll/src/main/java/fr/ird/observe/client/datasource/editor/ll/data/logbook/ActivitySampleUIMoveTreeAdapter.java ===================================== @@ -38,7 +38,7 @@ public class ActivitySampleUIMoveTreeAdapter extends DefaultSingleMoveTreeAdapte public static void moveFromActivityToActivity(NavigationTree tree, ActivitySampleUINavigationNode referenceNode, String activityId) { ActivityUINavigationNode newContainerNode = referenceNode.getParent().getParent() .getActivityUINavigationNode(activityId); - newContainerNode.refreshToRoot(); + newContainerNode.updateNode(); ActivitySampleUINavigationNode node = newContainerNode.getActivitySampleUINavigationNode(); tree.selectSafeNode(node); } @@ -46,7 +46,7 @@ public class ActivitySampleUIMoveTreeAdapter extends DefaultSingleMoveTreeAdapte public static void moveFromTripToActivity(NavigationTree tree, SampleUINavigationNode referenceNode, String activityId) { ActivityUINavigationNode newContainerNode = referenceNode.getParent().getParent() .getLogbookActivityListUINavigationNode().getActivityUINavigationNode(activityId); - newContainerNode.reloadNodeData(); + newContainerNode.updateNode(); ActivitySampleUINavigationNode node = newContainerNode.getActivitySampleUINavigationNode(); tree.selectSafeNode(node); } ===================================== client/datasource/editor/ps/src/main/java/fr/ird/observe/client/datasource/editor/ps/data/PsTripActionHelper.java ===================================== @@ -24,7 +24,6 @@ package fr.ird.observe.client.datasource.editor.ps.data; import fr.ird.observe.client.datasource.editor.api.content.ContentUI; import fr.ird.observe.client.datasource.editor.api.content.data.TripActionHelper; -import fr.ird.observe.client.datasource.editor.api.content.data.list.ContentListUI; import fr.ird.observe.dto.data.DataDto; import fr.ird.observe.dto.data.ps.common.TripReference; @@ -40,11 +39,11 @@ public class PsTripActionHelper extends TripActionHelper { // Ready for v9 @SuppressWarnings("unused") - public static <D extends DataDto> Predicate<Class<D>> createNewLogbookActionPredicate(ContentListUI<D, ?, ?> ui) { + public static <D extends DataDto> Predicate<Class<D>> createNewLogbookActionPredicate(ContentUI ui) { return (Class<D> r) -> new PsTripActionHelper(ui).gotoTripLogbookTab(); } - public static <D extends DataDto> Predicate<Class<D>> createNewObservationActionPredicate(ContentListUI<D, ?, ?> ui) { + public static <D extends DataDto> Predicate<Class<D>> createNewObservationActionPredicate(ContentUI ui) { return (Class<D> r) -> new PsTripActionHelper(ui).gotoTripObservationTab(); } ===================================== client/datasource/editor/ps/src/main/java/fr/ird/observe/client/datasource/editor/ps/data/common/TripUIHandler.java ===================================== @@ -21,12 +21,11 @@ */ package fr.ird.observe.client.datasource.editor.ps.data.common; +import fr.ird.observe.client.datasource.editor.api.content.actions.create.CreateNewOpenableUI; import fr.ird.observe.client.datasource.editor.api.content.data.TripUIHelper; import fr.ird.observe.client.datasource.editor.api.content.data.open.ContentOpenableUILayoutFocusTraversalPolicy; -import fr.ird.observe.client.datasource.editor.api.content.data.open.actions.CreateNewOpenable; import fr.ird.observe.client.datasource.editor.api.content.spi.ContentUIReferenceCache; import fr.ird.observe.client.datasource.editor.ps.data.observation.ActivityUINavigationNode; -import fr.ird.observe.client.datasource.editor.ps.data.observation.RouteUINavigationNode; import fr.ird.observe.dto.data.ps.common.TripDto; import fr.ird.observe.dto.form.Form; @@ -61,16 +60,12 @@ class TripUIHandler extends GeneratedTripUIHandler { } @Override - protected void installCreateAction() { - super.installCreateAction(); - CreateNewOpenable.installAction(ui, - ui.getAddRoute(), - RouteUINavigationNode.SPI, - n -> ((TripUINavigationNode) n).getRouteListUINavigationNode()); - CreateNewOpenable.installAction(ui, - ui.getAddActivity(), - ActivityUINavigationNode.SPI, - n -> ((TripUINavigationNode) n).getRouteListUINavigationNode().getRouteUINavigationNode(ui.getModel().getClientUIContext().getObserveEditModel().getPs().getObservationRoute().getId()).getActivityListUINavigationNode()); + protected void installCreateNewAction() { + super.installCreateNewAction(); + CreateNewOpenableUI.installAction(ui, + ui.getAddActivity(), + ActivityUINavigationNode.SPI, + n -> ((TripUINavigationNode) n).getRouteListUINavigationNode().getRouteUINavigationNode(ui.getModel().getClientUIContext().getObserveEditModel().getPs().getObservationRoute().getId()).getActivityListUINavigationNode()); } @Override ===================================== client/datasource/editor/ps/src/main/java/fr/ird/observe/client/datasource/editor/ps/data/observation/RouteUIHandler.java ===================================== @@ -22,7 +22,6 @@ package fr.ird.observe.client.datasource.editor.ps.data.observation; import fr.ird.observe.client.datasource.editor.api.content.data.open.ContentOpenableUILayoutFocusTraversalPolicy; -import fr.ird.observe.client.datasource.editor.api.content.data.open.actions.CreateNewOpenable; import java.awt.Component; import java.awt.Container; @@ -51,13 +50,4 @@ class RouteUIHandler extends GeneratedRouteUIHandler { } }; } - - @Override - protected void installCreateAction() { - super.installCreateAction(); - CreateNewOpenable.installAction(ui, - ui.getAddActivity(), - ActivityUINavigationNode.SPI, - n -> ((RouteUINavigationNode) n).getActivityListUINavigationNode()); - } } ===================================== client/datasource/editor/spi/src/main/java/fr/ird/observe/client/datasource/editor/spi/content/CapabilityDescriptor.java ===================================== @@ -22,9 +22,13 @@ package fr.ird.observe.client.datasource.editor.spi.content; * #L% */ +import fr.ird.observe.dto.IdDto; import fr.ird.observe.dto.reference.DtoReference; import fr.ird.observe.spi.module.BusinessProject; +import fr.ird.observe.toolkit.dto.navigation.edit.EditNode; +import org.apache.commons.lang3.StringUtils; +import java.util.List; import java.util.Objects; import java.util.Optional; @@ -100,10 +104,19 @@ public class CapabilityDescriptor { " if (reference instanceof %1$s.%2$sReference) {\n" + " return actualPosition + getNode().getChildrenPosition((%1$s.%2$sReference) reference, %3$s);\n" + " }\n"; + public static final String INSTALL_CREATE_NEW_ACTION = "" + + " CreateNewOpenableUI.installAction(ui);\n"; + public static final String INSTALL_CREATE_NEW_ACTION_WITH_PREDICATE = "" + + " CreateNewOpenableUI.installAction(ui, %1$s.%2$s(ui));\n"; + public static final String INSTALL_CREATE_NEW_ACTION_WITH_PREDICATE2 = "" + + " CreateNewOpenableUI.installAction2(ui, %1$s.class, %2$s.class, %3$s.%4$s(ui));\n"; + public static final String INSTALL_CREATE_NEW_ACTION2 = "" + + " CreateNewOpenableUI.installAction2(ui, %1$s.class, %2$s.class, t-> true);\n"; private final ContentNodeType contentNodeType; private final CapacityNodeType capacityNodeType; private final String nodeTypeName; private final String optionalPredicate; + private final Class<? extends IdDto> optionalDtoType; private final Class<? extends DtoReference> optionalReferenceType; private final String nodeTypePackage; private final String nodeTypeSimpleName; @@ -113,13 +126,46 @@ public class CapabilityDescriptor { CapacityNodeType capacityNodeType = CapacityNodeType.parseKey(key); String optionalPredicate = capacityNodeType.getPredicate(key); Class<? extends DtoReference> optionalReferenceType = capacityNodeType.getReference(businessProject, nodeTypeName); - return new CapabilityDescriptor(contentNodeType, capacityNodeType, nodeTypeName, optionalPredicate, optionalReferenceType); + Class<? extends IdDto> optionalDtoType = contentNodeType.getDto(businessProject, nodeTypeName); + return new CapabilityDescriptor(contentNodeType, capacityNodeType, nodeTypeName, optionalPredicate, optionalDtoType, optionalReferenceType); } - public CapabilityDescriptor(ContentNodeType contentNodeType, CapacityNodeType capacityNodeType, String nodeTypeName, String optionalPredicate, Class<? extends DtoReference> optionalReferenceType) { + public static String generateCapabilityAddNewOpenAction(CapacityNodeType capacityNodeType, ContentNodeType contentNodeType, String nodeTypeName, List<String> imports, EditNode<?> editNode, String packageName, boolean notMainNode) { + if (contentNodeType == ContentNodeType.OPEN) { + if (notMainNode) { + if (editNode.getLevel() == 2) { + String predicateMethodName = String.format("createNew%sActionPredicate", StringUtils.capitalize(editNode.getSubModule().getName().toLowerCase())); + String helperName = StringUtils.capitalize(editNode.getModule().getName().toLowerCase()) + "TripActionHelper"; + imports.add(packageName.substring(0, packageName.lastIndexOf(".") + 1) + helperName); + return String.format(INSTALL_CREATE_NEW_ACTION_WITH_PREDICATE2, nodeTypeName, editNode.getType().getName(), helperName, predicateMethodName); + } + return String.format(INSTALL_CREATE_NEW_ACTION2, nodeTypeName, editNode.getType().getName()); + } + return INSTALL_CREATE_NEW_ACTION; + } + if (contentNodeType == ContentNodeType.LIST) { + if (editNode.getLevel() == 2) { + String predicateMethodName = String.format("createNew%sActionPredicate", StringUtils.capitalize(editNode.getSubModule().getName().toLowerCase())); + String helperName = StringUtils.capitalize(editNode.getModule().getName().toLowerCase()) + "TripActionHelper"; + imports.add(packageName.substring(0, packageName.lastIndexOf(".") + 1) + helperName); + if (notMainNode) { + return String.format(INSTALL_CREATE_NEW_ACTION_WITH_PREDICATE2, nodeTypeName, editNode.getType().getName(), helperName, predicateMethodName); + } + return String.format(INSTALL_CREATE_NEW_ACTION_WITH_PREDICATE, helperName, predicateMethodName); + } + if (notMainNode) { + return String.format(INSTALL_CREATE_NEW_ACTION2, nodeTypeName, editNode.getType().getName()); + } + return INSTALL_CREATE_NEW_ACTION; + } + return ""; + } + + public CapabilityDescriptor(ContentNodeType contentNodeType, CapacityNodeType capacityNodeType, String nodeTypeName, String optionalPredicate, Class<? extends IdDto> optionalDtoType, Class<? extends DtoReference> optionalReferenceType) { this.contentNodeType = Objects.requireNonNull(contentNodeType); this.capacityNodeType = Objects.requireNonNull(capacityNodeType); this.nodeTypeName = Objects.requireNonNull(nodeTypeName); + this.optionalDtoType = optionalDtoType; int lastIndex = nodeTypeName.lastIndexOf("."); nodeTypePackage = nodeTypeName.substring(0, lastIndex); nodeTypeSimpleName = nodeTypeName.substring(lastIndex + 1); @@ -160,6 +206,10 @@ public class CapabilityDescriptor { return optionalReferenceType; } + public Class<? extends IdDto> getOptionalDtoType() { + return optionalDtoType; + } + public String getOptionalReferenceTypeCleanSimpleName() { return optionalReferenceType.getSimpleName().replace("Reference", ""); } @@ -291,6 +341,10 @@ public class CapabilityDescriptor { } } + public String generateCapabilityAddNewOpenAction(List<String> imports, EditNode<?> editNode, String packageName, boolean notMainNode) { + return generateCapabilityAddNewOpenAction(capacityNodeType, contentNodeType, nodeTypeName, imports, editNode, packageName, notMainNode); + } + protected String getOptionalReferenceTypePackage() { return optionalReferenceType.getPackage().getName(); } ===================================== client/datasource/editor/spi/src/main/java/fr/ird/observe/client/datasource/editor/spi/content/ContentNodeType.java ===================================== @@ -49,6 +49,10 @@ import fr.ird.observe.client.datasource.editor.api.navigation.tree.NavigationNod import fr.ird.observe.client.datasource.editor.api.navigation.tree.root.RootNavigationContext; import fr.ird.observe.client.datasource.editor.api.navigation.tree.root.RootNavigationNode; import fr.ird.observe.client.datasource.editor.spi.DetectContentFiles; +import fr.ird.observe.dto.IdDto; +import fr.ird.observe.spi.module.BusinessModule; +import fr.ird.observe.spi.module.BusinessProject; +import io.ultreia.java4all.lang.Objects2; /** * Created on 15/11/2020. @@ -86,12 +90,22 @@ public enum ContentNodeType { public boolean accept(DetectContentFiles detectContentFiles, String jaxxUiPath) { return detectContentFiles.isContentOpenableUI(jaxxUiPath); } + + @Override + public Class<? extends IdDto> getDto(BusinessProject businessProject, String nodeTypeName) { + return getDto0(businessProject, nodeTypeName); + } }, LIST(ContentListUINavigationNode.class, ContentListUINavigationContext.class, ContentListUIModel.class) { @Override public boolean accept(DetectContentFiles detectContentFiles, String jaxxUiPath) { return detectContentFiles.isContentListUI(jaxxUiPath); } + + @Override + public Class<? extends IdDto> getDto(BusinessProject businessProject, String nodeTypeName) { + return getDto0(businessProject, nodeTypeName); + } }, REFERENTIAL_HOME(ReferentialHomeUINavigationNode.class, ReferentialHomeUINavigationContext.class, ReferentialHomeUIModel.class) { @Override @@ -139,4 +153,29 @@ public enum ContentNodeType { public Class<? extends ContentUIModel> getUiModelType() { return uiModelType; } + + + public Class<? extends IdDto> getDto(BusinessProject businessProject, String nodeTypeName) { + return null; + } + + Class<? extends IdDto> getDto0(BusinessProject businessProject, String nodeTypeName) { + String nodeTypePackage = nodeTypeName.substring(0, nodeTypeName.lastIndexOf(".")); + BusinessModule childBusinessModule = businessProject.getBusinessModule(nodeTypePackage); + String childReferenceName = nodeTypeName + .replace("ListUI", "UI") + .replace("UINavigationNode", "") + .replace("fr.ird.observe.client.datasource.editor", "fr.ird.observe.dto") + .replace(childBusinessModule.getName() + ".", "") + .replace("referential.", "referential." + childBusinessModule.getName() + ".") + .replace("data.", "data." + childBusinessModule.getName() + "."); + + String referenceTypePackage = childReferenceName.substring(0, childReferenceName.lastIndexOf('.')); + String referenceTypeSimpleName = childReferenceName.substring(childReferenceName.lastIndexOf('.') + 1) + "Dto"; + if (referenceTypeSimpleName.startsWith("Activity") && !referenceTypeSimpleName.startsWith("ActivityD")) { + referenceTypeSimpleName = referenceTypeSimpleName.substring("Activity".length()); + } + return Objects2.forName(referenceTypePackage + "." + referenceTypeSimpleName); + } + } ===================================== client/datasource/editor/spi/src/main/java/fr/ird/observe/client/datasource/editor/spi/content/helper/ContentUIHandlerHelper.java ===================================== @@ -22,10 +22,15 @@ package fr.ird.observe.client.datasource.editor.spi.content.helper; * #L% */ -import fr.ird.observe.client.datasource.editor.api.content.data.list.actions.CreateNew; +import fr.ird.observe.client.datasource.editor.api.content.actions.create.CreateNewOpenableUI; import fr.ird.observe.client.datasource.editor.api.content.data.list.actions.MoveMultiple; import fr.ird.observe.client.datasource.editor.api.content.data.open.actions.MoveOpenable; +import fr.ird.observe.client.datasource.editor.spi.content.CapabilityDescriptor; +import fr.ird.observe.client.datasource.editor.spi.content.CapacityNodeType; +import fr.ird.observe.client.datasource.editor.spi.content.ContentNodeType; import fr.ird.observe.client.datasource.editor.spi.content.GenerateContentUISupport; +import fr.ird.observe.client.datasource.editor.spi.content.GenerateJavaFileSupport; +import fr.ird.observe.dto.IdDto; import fr.ird.observe.toolkit.dto.navigation.edit.EditNode; import fr.ird.observe.toolkit.dto.navigation.select.SelectNode; import org.apache.commons.lang3.StringUtils; @@ -63,15 +68,10 @@ public class ContentUIHandlerHelper extends ContentUIHelperSupport { " protected void installMoveAction() {\n" + " MoveMultiple.installMoveAction(ui, ui.getModel().getParentService()::%1$s);\n" + " }\n\n"; - public static final String INSTALL_CREATE_NEW_ACTION = "" + + public static final String INSTALL_CREATE_NEW_ACTION_METHOD = "" + " @Override\n" + " protected void installCreateNewAction() {\n" + - " CreateNew.installAction(ui);\n" + - " }\n\n"; - public static final String INSTALL_CREATE_NEW_ACTION_WITH_PREDICATE = "" + - " @Override\n" + - " protected void installCreateNewAction() {\n" + - " CreateNew.installAction(ui, %1$s.%2$s(ui));\n" + + "%2$s" + " }\n\n"; public static final String ON_END_OPEN_UI = "" + " @Override\n" + @@ -80,6 +80,39 @@ public class ContentUIHandlerHelper extends ContentUIHelperSupport { " super.onEndOpenUI();\n" + " }\n\n"; + + public static String generateCreateNewAction(List<String> imports, GenerateJavaFileSupport generator, EditNode<?> editNode) { + StringBuilder createChildrenMethodBuilder = new StringBuilder(); + String mainMethod = CapabilityDescriptor.generateCapabilityAddNewOpenAction(CapacityNodeType.REFERENCE, ContentNodeType.OPEN, generator.scopeBuilder.nodeType, imports, editNode, generator.packageName, false); + createChildrenMethodBuilder.append(mainMethod); + if (generator.capabilitiesDescriptor != null) { + for (CapabilityDescriptor capabilityDescriptor : generator.capabilitiesDescriptor) { + Class<? extends IdDto> dtoType = capabilityDescriptor.getOptionalDtoType(); + if (dtoType == null) { + continue; + } + EditNode<?> childEditNode = generator.editModel.forDtoType(dtoType).orElse(null); + if (childEditNode != null) { + String addNodeMethod = capabilityDescriptor.generateCapabilityAddNewOpenAction(imports, childEditNode, generator.packageName, true); + createChildrenMethodBuilder.append(addNodeMethod); + } + } + } + return String.format(INSTALL_CREATE_NEW_ACTION_METHOD, generator.cleanClassName, createChildrenMethodBuilder.toString()); + } + + public static String generateListCreateNewAction(List<String> imports, GenerateJavaFileSupport generator, EditNode<?> editNode) { + StringBuilder createChildrenMethodBuilder = new StringBuilder(); + String mainMethod = CapabilityDescriptor.generateCapabilityAddNewOpenAction(CapacityNodeType.REFERENCE, ContentNodeType.OPEN, generator.scopeBuilder.nodeChildType, imports, editNode, generator.packageName, false); + createChildrenMethodBuilder.append(mainMethod); +// for (CapabilityDescriptor capabilityDescriptor : generator.capabilitiesDescriptor) { +// capabilityDescriptor.getOptionalReferenceType() +// String addNodeMethod = capabilityDescriptor.generateCapabilityAddNewOpenAction(imports, editNode, generator.packageName, true); +// createChildrenMethodBuilder.append(addNodeMethod); +// } + return String.format(INSTALL_CREATE_NEW_ACTION_METHOD, generator.cleanClassName, createChildrenMethodBuilder.toString()); + } + public ContentUIHandlerHelper(GenerateContentUISupport generator) { super(generator); } @@ -101,7 +134,9 @@ public class ContentUIHandlerHelper extends ContentUIHelperSupport { if (editNode.getLevel() == 1) { methodName = "getParentBrothers"; } + imports.add(CreateNewOpenableUI.class.getName()); extraMethods += String.format(INSTALL_MOVE_SIMPLE_ACTION, methodName); + extraMethods += generateCreateNewAction(imports, generator, editNode); } return generate(ContentUIHandlerHelper.UI_HANDLER_GENERATED, imports, generator.cleanClassName, uiHandler, dtoType, extraMethods); } @@ -110,20 +145,12 @@ public class ContentUIHandlerHelper extends ContentUIHelperSupport { String helperName = StringUtils.capitalize(editNode.getModule().getName().toLowerCase()) + "TripActionHelper"; imports.add(generator.packageName.substring(0, generator.packageName.lastIndexOf(".") + 1) + helperName); imports.add(MoveMultiple.class.getName()); - imports.add(CreateNew.class.getName()); - switch (editNode.getLevel()) { - case 1: - extraMethods += String.format(ON_END_OPEN_UI, helperName); - extraMethods += INSTALL_CREATE_NEW_ACTION; - methodName = "getParentBrothers"; - break; - case 2: - String predicateMethodName = String.format("createNew%sActionPredicate", StringUtils.capitalize(editNode.getSubModule().getName().toLowerCase())); - extraMethods += String.format(INSTALL_CREATE_NEW_ACTION_WITH_PREDICATE, helperName, predicateMethodName); - break; - default: - extraMethods += INSTALL_CREATE_NEW_ACTION; + imports.add(CreateNewOpenableUI.class.getName()); + if (editNode.getLevel() == 1) { + extraMethods += String.format(ON_END_OPEN_UI, helperName); + methodName = "getParentBrothers"; } + extraMethods += generateListCreateNewAction(imports, generator, editNode); extraMethods += String.format(INSTALL_MOVE_ACTION, methodName); return generate(ContentUIHandlerHelper.UI_HANDLER_GENERATED2, imports, generator.cleanClassName, uiHandler, dtoType, extraType, extraMethods); } View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/commit/fb640b84faa41874e6b8d447f0... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/commit/fb640b84faa41874e6b8d447f0... You're receiving this email because of your account on gitlab.com.
participants (1)
-
Tony CHEMIT