Make layer switching more robust
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 20 Sep 2022 06:39:26 +0000 (08:39 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 20 Sep 2022 06:39:26 +0000 (08:39 +0200)
org.argeo.app.api/src/org/argeo/app/api/RankedObject.java
org.argeo.app.ui/src/org/argeo/app/ui/SuiteApp.java
org.argeo.app.ui/src/org/argeo/app/ui/SuiteUi.java
org.argeo.app.ui/src/org/argeo/app/ui/dialogs/NewUserWizard.java
org.argeo.app.ui/src/org/argeo/app/ui/library/DocumentsUiService.java
org.argeo.app.ui/src/org/argeo/app/ui/people/PeopleEntryArea.java

index 31c43a781770a62b059fccf8be21c976201854a5..371cdaec3096a15c0c406373964ab93ca4e58e72 100644 (file)
@@ -70,6 +70,18 @@ public class RankedObject<T> {
                return object.getClass().getName() + " with rank " + rank;
        }
 
+       public static <K, T> boolean hasHigherRank(Map<K, RankedObject<T>> map, K key, Map<String, Object> properties) {
+               if (!map.containsKey(key))
+                       return true;
+               RankedObject<T> rankedObject = new RankedObject<>(null, properties);
+               RankedObject<T> current = map.get(key);
+               return current.getRank() < rankedObject.getRank();
+       }
+
+       /**
+        * @return the {@link RankedObject}, or <code>null</code> if the current one was
+        *         kept
+        */
        public static <K, T> RankedObject<T> putIfHigherRank(Map<K, RankedObject<T>> map, K key, T object,
                        Map<String, Object> properties) {
                RankedObject<T> rankedObject = new RankedObject<>(object, properties);
@@ -81,14 +93,18 @@ public class RankedObject<T> {
                        return rankedObject;
                } else {
                        RankedObject<T> current = map.get(key);
-                       if (current.getRank() <= rankedObject.getRank()) {
+                       if (current.getRank() < rankedObject.getRank()) {
                                map.put(key, rankedObject);
-                               if (log.isTraceEnabled())
-                                       log.trace("Replaced " + key + " by " + object.getClass().getName() + " with rank "
+                               if (log.isDebugEnabled())
+                                       log.debug("Replaced " + key + " by " + object.getClass().getName() + " with rank "
                                                        + rankedObject.getRank());
                                return rankedObject;
+                       } else if (current.getRank() == rankedObject.getRank()) {
+                               log.error("Already " + key + " by " + current.get().getClass().getName() + " with rank "
+                                               + rankedObject.getRank() + ", ignoring " + rankedObject.getClass().getName());
+                               return null;
                        } else {
-                               return current;
+                               return null;
                        }
                }
 
index 271010dbd32c226fd3efc996b8aacc0b75714bbb..9ad2673fc1216d79746a5de580c2a6b7f56dc359 100644 (file)
@@ -2,6 +2,7 @@ package org.argeo.app.ui;
 
 import static org.argeo.api.cms.ux.CmsView.CMS_VIEW_UID_PROPERTY;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -265,7 +266,7 @@ public class SuiteApp extends AbstractCmsApp implements CmsEventSubscriber {
                                setState(ui, state != null ? state : defaultLayerPid);
                        }
                } catch (Exception e) {
-                       CmsFeedback.show("Unexpected exception", e);
+                       CmsFeedback.error("Unexpected exception", e);
                }
        }
 
@@ -551,7 +552,7 @@ public class SuiteApp extends AbstractCmsApp implements CmsEventSubscriber {
                                        }
                                }
                        } catch (Exception e) {
-                               CmsFeedback.show("Cannot handle event " + event, e);
+                               CmsFeedback.error("Cannot handle event " + event, e);
 //                             log.error("Cannot handle event " + event, e);
                        }
                });
@@ -631,8 +632,9 @@ public class SuiteApp extends AbstractCmsApp implements CmsEventSubscriber {
                }
                if (properties.containsKey(EntityConstants.TYPE)) {
                        List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
-                       for (String type : types)
+                       for (String type : types) {
                                RankedObject.putIfHigherRank(uiProvidersByType, type, uiProvider, properties);
+                       }
                }
        }
 
@@ -658,12 +660,26 @@ public class SuiteApp extends AbstractCmsApp implements CmsEventSubscriber {
        }
 
        public void addLayer(SuiteLayer layer, Map<String, Object> properties) {
-               if (properties.containsKey(Constants.SERVICE_PID)) {
-                       String pid = (String) properties.get(Constants.SERVICE_PID);
+               if (!properties.containsKey(Constants.SERVICE_PID))
+                       throw new IllegalArgumentException("A layer must have an ID");
+               String pid = (String) properties.get(Constants.SERVICE_PID);
+               List<String> types = properties.containsKey(EntityConstants.TYPE)
+                               ? LangUtils.toStringList(properties.get(EntityConstants.TYPE))
+                               : new ArrayList<>();
+               if (types.isEmpty()) {
+                       RankedObject.putIfHigherRank(layersByPid, pid, layer, properties);
+               } else {
+                       if (layersByPid.containsKey(pid)) {
+                               RankedObject<SuiteLayer> current = layersByPid.get(pid);
+                               List<String> currentTypes = current.getProperties().containsKey(EntityConstants.TYPE)
+                                               ? LangUtils.toStringList(current.getProperties().get(EntityConstants.TYPE))
+                                               : new ArrayList<>();
+                               if (!types.containsAll(currentTypes)) {
+                                       throw new IllegalArgumentException("Higher-ranked layer " + pid + " contains only types " + types
+                                                       + ", while it must override all " + currentTypes);
+                               }
+                       }
                        RankedObject.putIfHigherRank(layersByPid, pid, layer, properties);
-               }
-               if (properties.containsKey(EntityConstants.TYPE)) {
-                       List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
                        for (String type : types)
                                RankedObject.putIfHigherRank(layersByType, type, layer, properties);
                }
index f4464ba0265708f4eba04d6709eea28b8ca6257d..2e27d6a439854b9ab06bbab40156fdd0de1bf289 100644 (file)
@@ -140,12 +140,12 @@ class SuiteUi extends Composite implements CmsUi {
                }
        }
 
-       Composite switchToLayer(SuiteLayer layer, Content context) {
+       void switchToLayer(SuiteLayer layer, Content context) {
                // TODO make it more robust
                for (String layerId : layers.keySet()) {
                        SuiteLayer l = layers.get(layerId);
                        if (layer == l) {
-                               return switchToLayer(layerId, context);
+                               switchToLayer(layerId, context);
                        }
                }
                throw new IllegalArgumentException("Layer is not registered.");
index 207187279c46d4b48b3dd87b8214b72269a2e995..5c7a6d2231920114ec98b13a96fd796eacc264e3 100644 (file)
@@ -2,14 +2,13 @@ package org.argeo.app.ui.dialogs;
 
 import static org.argeo.eclipse.ui.EclipseUiUtils.isEmpty;
 
-import javax.jcr.Node;
-
 import org.argeo.app.ui.SuiteMsg;
 import org.argeo.app.ui.SuiteUiUtils;
+import org.argeo.cms.swt.dialogs.CmsFeedback;
+import org.argeo.cms.swt.widgets.SwtGuidedFormPage;
+import org.argeo.cms.ux.widgets.AbstractGuidedForm;
 import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardPage;
+import org.argeo.util.directory.HierarchyUnit;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
@@ -19,20 +18,20 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Text;
 
 /** Ask first & last name. Update the passed node on finish */
-public class NewUserWizard extends Wizard {
+public class NewUserWizard extends AbstractGuidedForm {
        // private final static Log log = LogFactory.getLog(NewPersonWizard.class);
 
        // Context
-       private Node person;
-
+//     private Node person;
+       private HierarchyUnit hierarchyUnit;
        // This page widgets
        protected Text lastNameTxt;
        protected Text firstNameTxt;
        // private Button useDistinctDisplayNameBtn;
        // private Text displayNameTxt;
 
-       public NewUserWizard(Node person) {
-               this.person = person;
+       public NewUserWizard(HierarchyUnit hierarchyUnit) {
+               this.hierarchyUnit = hierarchyUnit;
        }
 
        @Override
@@ -43,7 +42,7 @@ public class NewUserWizard extends Wizard {
                } catch (Exception e) {
                        throw new RuntimeException("Cannot add page to wizard", e);
                }
-               setWindowTitle(SuiteMsg.personWizardWindowTitle.lead());
+               setFormTitle(SuiteMsg.personWizardWindowTitle.lead());
        }
 
        /**
@@ -57,8 +56,9 @@ public class NewUserWizard extends Wizard {
                // String displayName = displayNameTxt.getText();
                // boolean useDistinct = useDistinctDisplayNameBtn.getSelection();
                if (EclipseUiUtils.isEmpty(lastName) && EclipseUiUtils.isEmpty(firstName)) {
-                       MessageDialog.openError(getShell(), "Non-valid information",
-                                       "Please enter at least a name that is not empty.");
+//                     MessageDialog.openError(getShell(), "Non-valid information",
+//                                     "Please enter at least a name that is not empty.");
+                       CmsFeedback.show("Please enter at least a name that is not empty.");
                        return false;
                } else {
 //                     ConnectJcrUtils.setJcrProperty(person, PEOPLE_LAST_NAME, PropertyType.STRING, lastName);
@@ -84,8 +84,7 @@ public class NewUserWizard extends Wizard {
                        return true;
        }
 
-       protected class MainInfoPage extends WizardPage {
-               private static final long serialVersionUID = 1L;
+       protected class MainInfoPage extends SwtGuidedFormPage {
 
                public MainInfoPage(String pageName) {
                        super(pageName);
@@ -135,7 +134,7 @@ public class NewUserWizard extends Wizard {
 
                                @Override
                                public void modifyText(ModifyEvent event) {
-                                       getContainer().updateButtons();
+                                       getView().updateButtons();
                                }
                        };
 
@@ -144,7 +143,7 @@ public class NewUserWizard extends Wizard {
                        // displayNameTxt.addModifyListener(ml);
 
                        // Don't forget this.
-                       setControl(firstNameTxt);
+                       // setControl(firstNameTxt);
                        firstNameTxt.setFocus();
                }
        }
index 6cbe4aee4ade15f0e92b59cfac6f3ab1afc47542..55a5a94d3a31fa0b90c529b9c25460c7284a9957 100644 (file)
@@ -254,7 +254,7 @@ public class DocumentsUiService {
                                }
                        }
                } catch (Exception e) {
-                       CmsFeedback.show("Cannot import files to " + currFolderPath,e);
+                       CmsFeedback.error("Cannot import files to " + currFolderPath,e);
                }
                return false;
        }
index 6a23c04d3c9bc0111ce7291480930fa166f56b72..8ee656a6ffebe0bdff5842da25cd5d19e1c50f91 100644 (file)
@@ -25,12 +25,14 @@ import org.argeo.cms.swt.CmsSwtTheme;
 import org.argeo.cms.swt.CmsSwtUtils;
 import org.argeo.cms.swt.Selected;
 import org.argeo.cms.swt.acr.SwtUiProvider;
+import org.argeo.cms.swt.widgets.SwtGuidedFormDialog;
 import org.argeo.cms.swt.widgets.SwtTableView;
 import org.argeo.cms.swt.widgets.SwtTreeView;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ux.widgets.AbstractHierarchicalPart;
 import org.argeo.cms.ux.widgets.Column;
 import org.argeo.cms.ux.widgets.DefaultTabularPart;
+import org.argeo.cms.ux.widgets.GuidedForm;
 import org.argeo.cms.ux.widgets.HierarchicalPart;
 import org.argeo.osgi.useradmin.UserDirectory;
 import org.argeo.util.directory.HierarchyUnit;
@@ -239,8 +241,8 @@ public class PeopleEntryArea implements SwtUiProvider, CmsUiProvider {
 
                addItem.addSelectionListener((Selected) (e) -> {
                        // SuiteUtils.getOrCreateUserNode(adminSession, userDn);
-                       Wizard wizard = new NewUserWizard(null);
-                       CmsWizardDialog dialog = new CmsWizardDialog(parent.getShell(), wizard);
+                       GuidedForm wizard = new NewUserWizard(null);
+                       SwtGuidedFormDialog dialog = new SwtGuidedFormDialog(parent.getShell(), wizard);
                        // WizardDialog dialog = new WizardDialog(shell, wizard);
                        if (dialog.open() == Window.OK) {
                                // TODO create