Support JCR node types as entity types.
[gpl/argeo-suite.git] / org.argeo.suite.ui / src / org / argeo / suite / ui / SuiteApp.java
index ce6f7f1f8f91556f488867186133a290eace6023..ecb9ff781dbf0dd3eb8b21b0183ab0e57562834a 100644 (file)
@@ -8,13 +8,16 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.TreeSet;
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.api.NodeUtils;
 import org.argeo.cms.ui.AbstractCmsApp;
 import org.argeo.cms.ui.CmsTheme;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.AbstractCmsApp;
 import org.argeo.cms.ui.CmsTheme;
 import org.argeo.cms.ui.CmsUiProvider;
@@ -22,6 +25,9 @@ import org.argeo.cms.ui.CmsView;
 import org.argeo.cms.ui.dialogs.CmsFeedback;
 import org.argeo.cms.ui.util.CmsEvent;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.cms.ui.dialogs.CmsFeedback;
 import org.argeo.cms.ui.util.CmsEvent;
 import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.entity.EntityConstants;
+import org.argeo.entity.EntityNames;
+import org.argeo.entity.EntityType;
 import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.suite.RankedObject;
 import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.suite.RankedObject;
@@ -39,7 +45,8 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
        public final static String HEADER_PID = PID_PREFIX + "header";
        public final static String LEAD_PANE_PID = PID_PREFIX + "leadPane";
        public final static String LOGIN_SCREEN_PID = PID_PREFIX + "loginScreen";
        public final static String HEADER_PID = PID_PREFIX + "header";
        public final static String LEAD_PANE_PID = PID_PREFIX + "leadPane";
        public final static String LOGIN_SCREEN_PID = PID_PREFIX + "loginScreen";
-       public final static String DASHBOARD_LAYER_PID = PID_PREFIX + "dashboardLayer";
+       // public final static String DASHBOARD_LAYER_PID = PID_PREFIX +
+       // "dashboardLayer";
        public final static String DASHBOARD_PID = PID_PREFIX + "dashboard";
        public final static String RECENT_ITEMS_PID = PID_PREFIX + "recentItems";
 
        public final static String DASHBOARD_PID = PID_PREFIX + "dashboard";
        public final static String RECENT_ITEMS_PID = PID_PREFIX + "recentItems";
 
@@ -47,6 +54,7 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
        private final static String DEFAULT_THEME_ID = "org.argeo.suite.theme.default";
 
        private Map<String, RankedObject<CmsUiProvider>> uiProvidersByPid = Collections.synchronizedMap(new HashMap<>());
        private final static String DEFAULT_THEME_ID = "org.argeo.suite.theme.default";
 
        private Map<String, RankedObject<CmsUiProvider>> uiProvidersByPid = Collections.synchronizedMap(new HashMap<>());
+       private Map<String, RankedObject<CmsUiProvider>> uiProvidersByType = Collections.synchronizedMap(new HashMap<>());
        private Map<String, RankedObject<SuiteLayer>> layers = Collections.synchronizedSortedMap(new TreeMap<>());
 
        // TODO make more optimal or via CmsSession/CmsView
        private Map<String, RankedObject<SuiteLayer>> layers = Collections.synchronizedSortedMap(new TreeMap<>());
 
        // TODO make more optimal or via CmsSession/CmsView
@@ -132,7 +140,7 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
 //                             ui.addLayer("documents");
 //                             ui.addLayer("locations");
 //                             ui.addLayer("people");
 //                             ui.addLayer("documents");
 //                             ui.addLayer("locations");
 //                             ui.addLayer("people");
-                               ui.switchToLayer(DASHBOARD_LAYER_PID, context);
+                               // ui.switchToLayer(DASHBOARD_LAYER_PID, context);
 
 //                             refreshPart(findUiProvider(DASHBOARD_PID), ui.getTabbedArea().getCurrent(), context);
                                refreshPart(findUiProvider(LEAD_PANE_PID), ui.getLeadPane(), context);
 
 //                             refreshPart(findUiProvider(DASHBOARD_PID), ui.getTabbedArea().getCurrent(), context);
                                refreshPart(findUiProvider(LEAD_PANE_PID), ui.getLeadPane(), context);
@@ -154,6 +162,54 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
                        throw new IllegalArgumentException("No UI provider registered as " + pid);
                return uiProvidersByPid.get(pid).get();
        }
                        throw new IllegalArgumentException("No UI provider registered as " + pid);
                return uiProvidersByPid.get(pid).get();
        }
+
+       private CmsUiProvider findUiProvider(Node context) {
+               try {
+                       // mixins
+                       Set<String> types = new TreeSet<>();
+                       for (NodeType nodeType : context.getMixinNodeTypes()) {
+                               String typeName = nodeType.getName();
+                               if (uiProvidersByType.containsKey(typeName)) {
+                                       types.add(typeName);
+                               }
+                       }
+                       // primary node type
+                       {
+                               NodeType nodeType = context.getPrimaryNodeType();
+                               String typeName = nodeType.getName();
+                               if (uiProvidersByType.containsKey(typeName)) {
+                                       types.add(typeName);
+                               }
+                               for (NodeType mixin : nodeType.getDeclaredSupertypes()) {
+                                       if (uiProvidersByType.containsKey(mixin.getName())) {
+                                               types.add(mixin.getName());
+                                       }
+                               }
+                       }
+                       // entity type
+                       if (context.isNodeType(EntityType.entity.get())) {
+                               if (context.hasProperty(EntityNames.ENTITY_TYPE)) {
+                                       String typeName = context.getProperty(EntityNames.ENTITY_TYPE).getString();
+                                       if (uiProvidersByType.containsKey(typeName)) {
+                                               types.add(typeName);
+                                       }
+                               }
+                       }
+
+//                     if (context.getPath().equals("/")) {// root node
+//                             types.add("nt:folder");
+//                     }
+                       if (NodeUtils.isUserHome(context) && uiProvidersByType.containsKey("nt:folder")) {// home node
+                               types.add("nt:folder");
+                       }
+
+                       if (types.size() == 0)
+                               throw new IllegalArgumentException("No UI provider found for " + context);
+                       return uiProvidersByType.get(types.iterator().next()).get();
+               } catch (RepositoryException e) {
+                       throw new IllegalStateException(e);
+               }
+       }
 //     private CmsUiProvider findUiProvider(String pid, Node context) {
 //             CmsUiProvider found = null;
 //             if (pid != null) {
 //     private CmsUiProvider findUiProvider(String pid, Node context) {
 //             CmsUiProvider found = null;
 //             if (pid != null) {
@@ -248,31 +304,14 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
         */
 
        public void addUiProvider(CmsUiProvider uiProvider, Map<String, Object> properties) {
         */
 
        public void addUiProvider(CmsUiProvider uiProvider, Map<String, Object> properties) {
-//             RankingKey partKey = new RankingKey(properties);
-//             if (partKey.getPid() != null || partKey.getDataType() != null) {
-//                     uiProvidersByPid.put(partKey, uiProvider);
-//                     if (log.isDebugEnabled())
-//                             log.debug("Added UI provider " + partKey + " (" + uiProvider.getClass().getName() + ") to CMS app.");
-//             }
-
                if (properties.containsKey(Constants.SERVICE_PID)) {
                        String pid = (String) properties.get(Constants.SERVICE_PID);
                        RankedObject.putIfHigherRank(uiProvidersByPid, pid, uiProvider, properties);
                if (properties.containsKey(Constants.SERVICE_PID)) {
                        String pid = (String) properties.get(Constants.SERVICE_PID);
                        RankedObject.putIfHigherRank(uiProvidersByPid, pid, uiProvider, properties);
-//                     RankedObject<CmsUiProvider> rankedObject = new RankedObject<>(uiProvider, properties);
-//                     if (!uiProvidersByPid.containsKey(pid)) {
-//                             uiProvidersByPid.put(pid, rankedObject);
-//                             if (log.isDebugEnabled())
-//                                     log.debug("Added UI provider " + pid + " as " + uiProvider.getClass().getName() + " with rank "
-//                                                     + rankedObject.getRank());
-//                     } else {
-//                             RankedObject<CmsUiProvider> current = uiProvidersByPid.get(pid);
-//                             if (current.getRank() <= rankedObject.getRank()) {
-//                                     uiProvidersByPid.put(pid, rankedObject);
-//                                     if (log.isDebugEnabled())
-//                                             log.debug("Replaced UI provider " + pid + " by " + uiProvider.getClass().getName()
-//                                                             + " with rank " + rankedObject.getRank());
-//                             }
-//                     }
+               }
+               if (properties.containsKey(EntityConstants.TYPE)) {
+                       // TODO manage String arrays as well
+                       String type = (String) properties.get(EntityConstants.TYPE);
+                       RankedObject.putIfHigherRank(uiProvidersByType, type, uiProvider, properties);
                }
        }
 
                }
        }
 
@@ -311,21 +350,28 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
 
                // Specific UI related events
                SuiteUi ui = getRelatedUi(event);
 
                // Specific UI related events
                SuiteUi ui = getRelatedUi(event);
-               String currentLayerId = ui.getCurrentLayerId();
-               SuiteLayer layer = layers.get(currentLayerId).get();
-               if (isTopic(event, SuiteEvent.refreshPart)) {
-                       Node node = Jcr.getNodeById(ui.getSysSession(), get(event, SuiteEvent.NODE_ID));
-                       layer.view(ui.getCurrentWorkArea(), node);
-                       // ui.getTabbedArea().view(findUiProvider(DASHBOARD_PID), node);
-//                     ui.layout(true, true);
-               } else if (isTopic(event, SuiteEvent.openNewPart)) {
-                       Node node = Jcr.getNodeById(ui.getSysSession(), get(event, SuiteEvent.NODE_ID));
-                       layer.open(ui.getCurrentWorkArea(), node);
-//                     ui.getTabbedArea().open(findUiProvider(DASHBOARD_PID), node);
-//                     ui.layout(true, true);
-               } else if (isTopic(event, SuiteEvent.switchLayer)) {
-                       String layerId = get(event, SuiteEvent.LAYER);
-                       ui.switchToLayer(layerId, null);
+               try {
+                       String currentLayerId = ui.getCurrentLayerId();
+                       SuiteLayer layer = currentLayerId != null ? layers.get(currentLayerId).get() : null;
+                       if (isTopic(event, SuiteEvent.refreshPart)) {
+                               String nodeId = get(event, SuiteEvent.NODE_ID);
+                               String workspace = get(event, SuiteEvent.WORKSPACE);
+                               Node node = Jcr.getNodeById(ui.getSession(workspace), nodeId);
+                               CmsUiProvider uiProvider = findUiProvider(node);
+                               layer.view(uiProvider, ui.getCurrentWorkArea(), node);
+                       } else if (isTopic(event, SuiteEvent.openNewPart)) {
+                               String nodeId = get(event, SuiteEvent.NODE_ID);
+                               String workspace = get(event, SuiteEvent.WORKSPACE);
+                               Node node = Jcr.getNodeById(ui.getSession(workspace), nodeId);
+                               CmsUiProvider uiProvider = findUiProvider(node);
+                               layer.open(uiProvider, ui.getCurrentWorkArea(), node);
+                       } else if (isTopic(event, SuiteEvent.switchLayer)) {
+                               String layerId = get(event, SuiteEvent.LAYER);
+                               ui.switchToLayer(layerId, Jcr.getRootNode(ui.getSession(null)));
+                       }
+               } catch (Exception e) {
+                       log.error("Cannot handle event " + event, e);
+//                     CmsView.getCmsView(ui).exception(e);
                }
 
        }
                }
 
        }