Repository: syncope
Updated Branches:
  refs/heads/2_0_X c13f9e626 -> 65a0f14d4


[SYNCOPE-1067] provides the possibility to select for a dynamic realms and 
manage object inside it


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/65a0f14d
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/65a0f14d
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/65a0f14d

Branch: refs/heads/2_0_X
Commit: 65a0f14d49351b29ce8ba78b02916b9a72e7ad52
Parents: c13f9e6
Author: fmartelli <fabio.marte...@gmail.com>
Authored: Wed Jun 14 17:37:22 2017 +0200
Committer: fmartelli <fabio.marte...@gmail.com>
Committed: Wed Jun 14 17:37:22 2017 +0200

----------------------------------------------------------------------
 .../console/panels/AnyDirectoryPanel.java       |   6 +-
 .../console/panels/AnyObjectDirectoryPanel.java |   8 +-
 .../syncope/client/console/panels/AnyPanel.java |  68 ++++++---
 .../console/panels/GroupDirectoryPanel.java     |  11 ++
 .../syncope/client/console/panels/Realm.java    |  68 ++++-----
 .../client/console/panels/RealmChoicePanel.java | 143 ++++++++++++++++++-
 .../console/panels/UserDirectoryPanel.java      |  11 +-
 .../client/console/rest/RealmRestClient.java    |  12 ++
 .../META-INF/resources/css/syncopeConsole.css   |   4 +
 .../client/console/pages/Realms.properties      |   4 +
 .../client/console/pages/Realms_it.properties   |   4 +
 .../console/pages/Realms_pt_BR.properties       |   4 +
 .../client/console/pages/Realms_ru.properties   |   4 +
 .../client/console/panels/RealmChoicePanel.html |   2 +-
 .../syncope/fit/console/RealmsITCase.java       |   6 +-
 .../apache/syncope/fit/console/UsersITCase.java |   2 +-
 16 files changed, 291 insertions(+), 66 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
index 64cb0b0..4bc4b7b 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
@@ -43,6 +43,7 @@ import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.Bas
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wizards.any.AnyWrapper;
 import org.apache.syncope.client.console.wizards.any.StatusPanel;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
@@ -91,7 +92,8 @@ public abstract class AnyDirectoryPanel<A extends AnyTO, E 
extends AbstractAnyRe
 
     protected AnyDirectoryPanel(final String id, final Builder<A, E> builder, 
final boolean wizardInModal) {
         super(id, builder, wizardInModal);
-        if (SyncopeConsoleSession.get().owns(String.format("%s_CREATE", 
builder.type), builder.realm)) {
+        if (SyncopeConsoleSession.get().owns(String.format("%s_CREATE", 
builder.type), builder.realm)
+                && builder.realm.startsWith(SyncopeConstants.ROOT_REALM)) {
             MetaDataRoleAuthorizationStrategy.authorizeAll(addAjaxLink, 
RENDER);
         } else {
             MetaDataRoleAuthorizationStrategy.unauthorizeAll(addAjaxLink, 
RENDER);
@@ -176,7 +178,7 @@ public abstract class AnyDirectoryPanel<A extends AnyTO, E 
extends AbstractAnyRe
         /**
          * Realm related to current panel.
          */
-        protected String realm = "/";
+        protected String realm = SyncopeConstants.ROOT_REALM;
 
         /**
          * Any type related to current panel.

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
index a8a1207..75803d9 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
@@ -40,6 +40,7 @@ import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.client.console.wizards.any.AnyWrapper;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.types.AnyEntitlement;
@@ -172,7 +173,7 @@ public class AnyObjectDirectoryPanel extends 
AnyDirectoryPanel<AnyObjectTO, AnyO
 
             @Override
             protected boolean statusCondition(final AnyObjectTO modelObject) {
-                return addAjaxLink.isVisibleInHierarchy();
+                return addAjaxLink.isVisibleInHierarchy() && 
realm.startsWith(SyncopeConstants.ROOT_REALM);
             }
         }, ActionType.CLONE, 
AnyEntitlement.CREATE.getFor(type)).setRealm(realm);
 
@@ -250,6 +251,11 @@ public class AnyObjectDirectoryPanel extends 
AnyDirectoryPanel<AnyObjectTO, AnyO
                 }
                 ((BasePage) 
pageRef.getPage()).getNotificationPanel().refresh(target);
             }
+
+            @Override
+            protected boolean statusCondition(final AnyObjectTO modelObject) {
+                return realm.startsWith(SyncopeConstants.ROOT_REALM);
+            }
         }, ActionType.DELETE, AnyEntitlement.DELETE.getFor(type), 
true).setRealm(realm);
 
         return panel;

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyPanel.java
index 950e546..4b8f9de 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyPanel.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Triple;
 import org.apache.syncope.client.console.layout.AnyObjectFormLayoutInfo;
 import org.apache.syncope.client.console.layout.FormLayoutInfoUtils;
@@ -37,6 +38,7 @@ import 
org.apache.syncope.client.console.panels.search.UserSearchPanel;
 import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
 import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.tabs.Accordion;
 import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.GroupTO;
@@ -148,21 +150,32 @@ public class AnyPanel extends Panel implements ModalPanel 
{
         if (event.getPayload() instanceof SearchClausePanel.SearchEvent) {
             final AjaxRequestTarget target = 
SearchClausePanel.SearchEvent.class.cast(event.getPayload()).getTarget();
 
+            final String precond;
+
+            if (realmTO.getFullPath().startsWith(SyncopeConstants.ROOT_REALM)) 
{
+                precond = StringUtils.EMPTY;
+            } else {
+                precond = String.format("$dynRealms=~%s;", realmTO.getKey());
+            }
+
             switch (anyTypeTO.getKind()) {
                 case USER:
-                    
UserDirectoryPanel.class.cast(AnyPanel.this.directoryPanel).search(SearchUtils.buildFIQL(
-                            AnyPanel.this.searchPanel.getModel().getObject(),
-                            SyncopeClient.getUserSearchConditionBuilder()), 
target);
+                    
UserDirectoryPanel.class.cast(AnyPanel.this.directoryPanel).search(
+                            precond + SearchUtils.buildFIQL(
+                                    
AnyPanel.this.searchPanel.getModel().getObject(),
+                                    
SyncopeClient.getUserSearchConditionBuilder()), target);
                     break;
                 case GROUP:
-                    
GroupDirectoryPanel.class.cast(AnyPanel.this.directoryPanel).search(SearchUtils.buildFIQL(
-                            AnyPanel.this.searchPanel.getModel().getObject(),
-                            SyncopeClient.getGroupSearchConditionBuilder()), 
target);
+                    
GroupDirectoryPanel.class.cast(AnyPanel.this.directoryPanel).search(
+                            precond + SearchUtils.buildFIQL(
+                                    
AnyPanel.this.searchPanel.getModel().getObject(),
+                                    
SyncopeClient.getGroupSearchConditionBuilder()), target);
                     break;
                 case ANY_OBJECT:
-                    
AnyObjectDirectoryPanel.class.cast(AnyPanel.this.directoryPanel).search(SearchUtils.buildFIQL(
-                            AnyPanel.this.searchPanel.getModel().getObject(),
-                            
SyncopeClient.getAnyObjectSearchConditionBuilder(anyTypeTO.getKey())), target);
+                    
AnyObjectDirectoryPanel.class.cast(AnyPanel.this.directoryPanel).search(
+                            precond + SearchUtils.buildFIQL(
+                                    
AnyPanel.this.searchPanel.getModel().getObject(),
+                                    
SyncopeClient.getAnyObjectSearchConditionBuilder(anyTypeTO.getKey())), target);
                     break;
                 default:
             }
@@ -212,16 +225,30 @@ public class AnyPanel extends Panel implements ModalPanel 
{
 
     protected Panel getDirectoryPanel(final String id) {
         final Panel panel;
-        final String fiql;
+        String fiql;
+
+        final String realm;
+        final String dynRealm;
+        if (realmTO.getFullPath().startsWith(SyncopeConstants.ROOT_REALM)) {
+            realm = realmTO.getFullPath();
+            dynRealm = null;
+        } else {
+            realm = SyncopeConstants.ROOT_REALM;
+            dynRealm = realmTO.getKey();
+        }
+
         switch (anyTypeTO.getKind()) {
             case USER:
-                fiql = 
SyncopeClient.getUserSearchConditionBuilder().is("key").notNullValue().query();
+                fiql = dynRealm == null
+                        ? 
SyncopeClient.getUserSearchConditionBuilder().is("key").notNullValue().query()
+                        : 
SyncopeClient.getUserSearchConditionBuilder().inDynRealms(dynRealm).query();
+
                 final UserTO userTO = new UserTO();
                 userTO.setRealm(realmTO.getFullPath());
                 panel = new UserDirectoryPanel.Builder(
                         anyTypeClassRestClient.list(anyTypeTO.getClasses()),
                         anyTypeTO.getKey(),
-                        
pageRef).setRealm(realmTO.getFullPath()).setFiltered(true).
+                        pageRef).setRealm(dynRealm != null ? dynRealm : 
realm).setFiltered(true).
                         
setFiql(fiql).setWizardInModal(true).addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
                         userTO,
                         anyTypeTO.getClasses(),
@@ -231,13 +258,16 @@ public class AnyPanel extends Panel implements ModalPanel 
{
                 break;
 
             case GROUP:
-                fiql = 
SyncopeClient.getGroupSearchConditionBuilder().is("key").notNullValue().query();
+                fiql = dynRealm == null
+                        ? 
SyncopeClient.getGroupSearchConditionBuilder().is("key").notNullValue().query()
+                        : 
SyncopeClient.getGroupSearchConditionBuilder().inDynRealms(dynRealm).query();
+
                 final GroupTO groupTO = new GroupTO();
                 groupTO.setRealm(realmTO.getFullPath());
                 panel = new GroupDirectoryPanel.Builder(
                         anyTypeClassRestClient.list(anyTypeTO.getClasses()),
                         anyTypeTO.getKey(),
-                        
pageRef).setRealm(realmTO.getFullPath()).setFiltered(true).
+                        pageRef).setRealm(dynRealm != null ? dynRealm : 
realm).setFiltered(true).
                         
setFiql(fiql).setWizardInModal(true).addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
                         groupTO,
                         anyTypeTO.getClasses(),
@@ -247,15 +277,19 @@ public class AnyPanel extends Panel implements ModalPanel 
{
                 break;
 
             case ANY_OBJECT:
-                fiql = 
SyncopeClient.getAnyObjectSearchConditionBuilder(anyTypeTO.getKey()).is("key").notNullValue().
-                        query();
+                fiql = dynRealm == null
+                        ? 
SyncopeClient.getAnyObjectSearchConditionBuilder(anyTypeTO.getKey()).is("key").notNullValue()
+                        .query()
+                        : 
SyncopeClient.getAnyObjectSearchConditionBuilder(anyTypeTO.getKey()).inDynRealms(dynRealm)
+                        .query();
+
                 final AnyObjectTO anyObjectTO = new AnyObjectTO();
                 anyObjectTO.setRealm(realmTO.getFullPath());
                 anyObjectTO.setType(anyTypeTO.getKey());
                 panel = new AnyObjectDirectoryPanel.Builder(
                         anyTypeClassRestClient.list(anyTypeTO.getClasses()),
                         anyTypeTO.getKey(),
-                        
pageRef).setRealm(realmTO.getFullPath()).setFiltered(true).
+                        pageRef).setRealm(dynRealm != null ? dynRealm : 
realm).setFiltered(true).
                         
setFiql(fiql).setWizardInModal(true).addNewItemPanelBuilder(FormLayoutInfoUtils.instantiate(
                         anyObjectTO,
                         anyTypeTO.getClasses(),

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
index 889bf8f..0191c3e 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
@@ -48,6 +48,7 @@ import 
org.apache.syncope.client.console.wizards.any.AnyWrapper;
 import org.apache.syncope.client.console.wizards.any.GroupWrapper;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
@@ -270,6 +271,11 @@ public class GroupDirectoryPanel extends 
AnyDirectoryPanel<GroupTO, GroupRestCli
                 send(GroupDirectoryPanel.this, Broadcast.EXACT,
                         new AjaxWizard.NewItemActionEvent<>(new 
GroupWrapper(clone), target));
             }
+
+            @Override
+            protected boolean statusCondition(final GroupTO modelObject) {
+                return realm.startsWith(SyncopeConstants.ROOT_REALM);
+            }
         }, ActionType.CLONE, StandardEntitlement.GROUP_CREATE).setRealm(realm);
 
         panel.add(new ActionLink<GroupTO>() {
@@ -410,6 +416,11 @@ public class GroupDirectoryPanel extends 
AnyDirectoryPanel<GroupTO, GroupRestCli
                 }
                 ((BasePage) 
pageRef.getPage()).getNotificationPanel().refresh(target);
             }
+
+            @Override
+            protected boolean statusCondition(final GroupTO modelObject) {
+                return realm.startsWith(SyncopeConstants.ROOT_REALM);
+            }
         }, ActionType.DELETE, StandardEntitlement.GROUP_DELETE, 
true).setRealm(realm);
 
         return panel;

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
index e6d57cd..17338c1 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -43,6 +43,7 @@ import 
org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.client.console.wizards.any.ConnObjectPanel;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.PropagationStatus;
@@ -83,8 +84,8 @@ public abstract class Realm extends WizardMgtPanel<RealmTO> {
 
         setPageRef(pageRef);
 
-        AjaxBootstrapTabbedPanel<ITab> tabbedPanel =
-                new AjaxBootstrapTabbedPanel<>("tabbedPanel", 
buildTabList(pageRef));
+        AjaxBootstrapTabbedPanel<ITab> tabbedPanel
+                = new AjaxBootstrapTabbedPanel<>("tabbedPanel", 
buildTabList(pageRef));
         tabbedPanel.setSelectedTab(selectedIndex);
         addInnerObject(tabbedPanel);
         this.wizardBuilder = new RealmWizardBuilder(pageRef);
@@ -112,46 +113,49 @@ public abstract class Realm extends 
WizardMgtPanel<RealmTO> {
             public Panel getPanel(final String panelId) {
                 final ActionsPanel<RealmTO> actionPanel = new 
ActionsPanel<>("actions", null);
 
-                actionPanel.add(new ActionLink<RealmTO>(realmTO) {
+                if 
(realmTO.getFullPath().startsWith(SyncopeConstants.ROOT_REALM)) {
 
-                    private static final long serialVersionUID = 
2802988981431379827L;
+                    actionPanel.add(new ActionLink<RealmTO>(realmTO) {
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final 
RealmTO ignore) {
-                        onClickCreate(target);
-                    }
-                }, ActionLink.ActionType.CREATE, 
StandardEntitlement.REALM_CREATE).hideLabel();
+                        private static final long serialVersionUID = 
2802988981431379827L;
 
-                actionPanel.add(new ActionLink<RealmTO>(realmTO) {
+                        @Override
+                        public void onClick(final AjaxRequestTarget target, 
final RealmTO ignore) {
+                            onClickCreate(target);
+                        }
+                    }, ActionLink.ActionType.CREATE, 
StandardEntitlement.REALM_CREATE).hideLabel();
 
-                    private static final long serialVersionUID = 
2802988981431379828L;
+                    actionPanel.add(new ActionLink<RealmTO>(realmTO) {
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final 
RealmTO ignore) {
-                        onClickEdit(target, realmTO);
-                    }
-                }, ActionLink.ActionType.EDIT, 
StandardEntitlement.REALM_UPDATE).hideLabel();
+                        private static final long serialVersionUID = 
2802988981431379828L;
 
-                actionPanel.add(new ActionLink<RealmTO>(realmTO) {
+                        @Override
+                        public void onClick(final AjaxRequestTarget target, 
final RealmTO ignore) {
+                            onClickEdit(target, realmTO);
+                        }
+                    }, ActionLink.ActionType.EDIT, 
StandardEntitlement.REALM_UPDATE).hideLabel();
 
-                    private static final long serialVersionUID = 
2802988981431379827L;
+                    actionPanel.add(new ActionLink<RealmTO>(realmTO) {
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final 
RealmTO ignore) {
-                        onClickTemplate(target);
-                    }
-                }, ActionLink.ActionType.TEMPLATE, 
StandardEntitlement.REALM_UPDATE).hideLabel();
+                        private static final long serialVersionUID = 
2802988981431379827L;
 
-                actionPanel.add(new ActionLink<RealmTO>(realmTO) {
+                        @Override
+                        public void onClick(final AjaxRequestTarget target, 
final RealmTO ignore) {
+                            onClickTemplate(target);
+                        }
+                    }, ActionLink.ActionType.TEMPLATE, 
StandardEntitlement.REALM_UPDATE).hideLabel();
 
-                    private static final long serialVersionUID = 
2802988981431379829L;
+                    actionPanel.add(new ActionLink<RealmTO>(realmTO) {
 
-                    @Override
-                    public void onClick(final AjaxRequestTarget target, final 
RealmTO ignore) {
-                        onClickDelete(target, realmTO);
-                    }
-                }, ActionLink.ActionType.DELETE, 
StandardEntitlement.REALM_DELETE, true).hideLabel();
+                        private static final long serialVersionUID = 
2802988981431379829L;
 
+                        @Override
+                        public void onClick(final AjaxRequestTarget target, 
final RealmTO ignore) {
+                            onClickDelete(target, realmTO);
+                        }
+                    }, ActionLink.ActionType.DELETE, 
StandardEntitlement.REALM_DELETE, true).hideLabel();
+                }
+                
                 RealmDetails panel = new RealmDetails(panelId, realmTO, 
actionPanel, false);
                 panel.setContentEnabled(false);
                 actionPanel.setEnabled(true);
@@ -165,8 +169,8 @@ public abstract class Realm extends WizardMgtPanel<RealmTO> 
{
             }
         });
 
-        final Triple<UserFormLayoutInfo, GroupFormLayoutInfo, Map<String, 
AnyObjectFormLayoutInfo>> formLayoutInfo =
-                FormLayoutInfoUtils.fetch(anyTypeTOs);
+        final Triple<UserFormLayoutInfo, GroupFormLayoutInfo, Map<String, 
AnyObjectFormLayoutInfo>> formLayoutInfo
+                = FormLayoutInfoUtils.fetch(anyTypeTOs);
 
         Collections.sort(anyTypeTOs, new AnyTypeComparator());
         for (final AnyTypeTO anyTypeTO : anyTypeTOs) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
index 2d985ef..2204289 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmChoicePanel.java
@@ -39,12 +39,15 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.rest.RealmRestClient;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.DynRealmTO;
 import org.apache.syncope.common.lib.to.RealmTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import 
org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
 import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.link.AbstractLink;
@@ -61,7 +64,9 @@ public class RealmChoicePanel extends Panel {
 
     private final PageReference pageRef;
 
-    private final LoadableDetachableModel<List<Pair<String, RealmTO>>> ldm;
+    private final LoadableDetachableModel<List<Pair<String, RealmTO>>> 
realmTree;
+
+    private final LoadableDetachableModel<List<DynRealmTO>> dynRealmTree;
 
     private final WebMarkupContainer container;
 
@@ -77,11 +82,11 @@ public class RealmChoicePanel extends Panel {
         tree = new HashMap<>();
 
         RealmTO fakeRootRealm = new RealmTO();
-        fakeRootRealm.setName("/");
-        fakeRootRealm.setFullPath("/");
+        fakeRootRealm.setName(SyncopeConstants.ROOT_REALM);
+        fakeRootRealm.setFullPath(SyncopeConstants.ROOT_REALM);
         model = Model.of(fakeRootRealm);
 
-        ldm = new LoadableDetachableModel<List<Pair<String, RealmTO>>>() {
+        realmTree = new LoadableDetachableModel<List<Pair<String, RealmTO>>>() 
{
 
             private static final long serialVersionUID = -7688359318035249200L;
 
@@ -111,7 +116,31 @@ public class RealmChoicePanel extends Panel {
             }
         };
 
-        container = new WebMarkupContainer("container", ldm);
+        dynRealmTree = new LoadableDetachableModel<List<DynRealmTO>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected List<DynRealmTO> load() {
+                final List<DynRealmTO> dynRealms = 
realmRestClient.listDynReams();
+                dynRealms.sort(new Comparator<DynRealmTO>() {
+
+                    @Override
+                    public int compare(final DynRealmTO left, final DynRealmTO 
right) {
+                        if (left == null) {
+                            return -1;
+                        } else if (right == null) {
+                            return 1;
+                        } else {
+                            return left.getKey().compareTo(right.getKey());
+                        }
+                    }
+                });
+                return dynRealms;
+            }
+        };
+
+        container = new WebMarkupContainer("container", realmTree);
         container.setOutputMarkupId(true);
         add(container);
 
@@ -121,6 +150,17 @@ public class RealmChoicePanel extends Panel {
     }
 
     public final void reloadRealmTree() {
+        final Label realmLabel = new Label("realmLabel", new Model<String>());
+        realmLabel.setOutputMarkupId(true);
+
+        container.addOrReplace(realmLabel);
+
+        if 
(model.getObject().getFullPath().startsWith(SyncopeConstants.ROOT_REALM)) {
+            realmLabel.setDefaultModel(new ResourceModel("realmLabel", 
"Realm"));
+        } else {
+            realmLabel.setDefaultModel(new ResourceModel("dynRealmLabel", 
"Dynamic Realm"));
+        }
+
         final Label label = new Label("realm", 
model.getObject().getFullPath());
         label.setOutputMarkupId(true);
         container.addOrReplace(label);
@@ -134,7 +174,32 @@ public class RealmChoicePanel extends Panel {
             protected List<AbstractLink> newSubMenuButtons(final String 
buttonMarkupId) {
                 List<AbstractLink> links = new ArrayList<>();
 
-                for (Pair<String, RealmTO> link : ldm.getObject()) {
+                links.add(new BootstrapAjaxLink<String>(
+                        ButtonList.getButtonMarkupId(),
+                        new Model<String>(),
+                        Buttons.Type.Link,
+                        new ResourceModel("realms", "Realms")) {
+
+                    private static final long serialVersionUID = 
-7978723352517770744L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+
+                    }
+
+                    @Override
+                    public boolean isEnabled() {
+                        return false;
+                    }
+
+                    @Override
+                    protected void onComponentTag(final ComponentTag tag) {
+                        tag.put("class", "panel box box-primary box-header 
with-border");
+                        tag.put("style", "margin: 20px 5px 0px 5px; width: 
90%");
+                    }
+                });
+
+                for (Pair<String, RealmTO> link : realmTree.getObject()) {
                     final RealmTO realmTO = link.getValue();
                     links.add(new BootstrapAjaxLink<String>(
                             ButtonList.getButtonMarkupId(),
@@ -148,6 +213,7 @@ public class RealmChoicePanel extends Panel {
                         public void onClick(final AjaxRequestTarget target) {
                             model.setObject(realmTO);
                             
label.setDefaultModelObject(model.getObject().getFullPath());
+                            realmLabel.setDefaultModel(new 
ResourceModel("realmLabel", "Realm"));
                             target.add(label);
                             send(pageRef.getPage(), Broadcast.EXACT, new 
ChosenRealm<>(realmTO, target));
                         }
@@ -164,6 +230,71 @@ public class RealmChoicePanel extends Panel {
                         }
                     });
                 }
+
+                if (!dynRealmTree.getObject().isEmpty()) {
+                    links.add(new BootstrapAjaxLink<String>(
+                            ButtonList.getButtonMarkupId(),
+                            new Model<String>(),
+                            Buttons.Type.Link,
+                            new ResourceModel("dynrealms", "Dynamic Realms")) {
+
+                        private static final long serialVersionUID = 
-7978723352517770744L;
+
+                        @Override
+                        public void onClick(final AjaxRequestTarget target) {
+
+                        }
+
+                        @Override
+                        public boolean isEnabled() {
+                            return false;
+                        }
+
+                        @Override
+                        protected void onComponentTag(final ComponentTag tag) {
+                            tag.put("class", "panel box box-primary box-header 
with-border");
+                            tag.put("style", "margin: 20px 5px 0px 5px; width: 
90%");
+                        }
+                    });
+
+                    for (DynRealmTO dynRealmTO : dynRealmTree.getObject()) {
+                        final RealmTO realmTO = new RealmTO();
+                        realmTO.setKey(dynRealmTO.getKey());
+                        realmTO.setName(dynRealmTO.getKey());
+                        realmTO.setFullPath(dynRealmTO.getKey());
+
+                        links.add(new BootstrapAjaxLink<String>(
+                                ButtonList.getButtonMarkupId(),
+                                new Model<String>(),
+                                Buttons.Type.Link,
+                                new Model<>(realmTO.getKey())) {
+
+                            private static final long serialVersionUID = 
-7978723352517770644L;
+
+                            @Override
+                            public void onClick(final AjaxRequestTarget 
target) {
+                                model.setObject(realmTO);
+                                label.setDefaultModelObject(realmTO.getKey());
+                                realmLabel.setDefaultModel(new 
ResourceModel("dynRealmLabel", "Dynamic Realm"));
+                                target.add(label);
+                                send(pageRef.getPage(), Broadcast.EXACT, new 
ChosenRealm<>(realmTO, target));
+                            }
+
+                            @Override
+                            public boolean isEnabled() {
+                                return 
IterableUtils.matchesAny(availableRealms, new Predicate<String>() {
+
+                                    @Override
+                                    public boolean evaluate(final String 
availableRealm) {
+                                        return "/".equals(availableRealm)
+                                                || 
realmTO.getKey().equals(availableRealm);
+                                    }
+                                });
+                            }
+                        });
+                    }
+                }
+
                 return links;
             }
         };

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
index dae614f..717a955 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
@@ -42,6 +42,7 @@ import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
 import org.apache.syncope.client.console.wizards.any.AnyWrapper;
 import org.apache.syncope.client.console.wizards.any.UserWrapper;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -198,9 +199,8 @@ public class UserDirectoryPanel extends 
AnyDirectoryPanel<UserTO, UserRestClient
 
             @Override
             protected boolean statusCondition(final UserTO modelObject) {
-                return addAjaxLink.isVisibleInHierarchy();
+                return addAjaxLink.isVisibleInHierarchy() && 
realm.startsWith(SyncopeConstants.ROOT_REALM);
             }
-
         }, ActionType.CLONE, StandardEntitlement.USER_CREATE).setRealm(realm);
 
         panel.add(new ActionLink<UserTO>() {
@@ -310,7 +310,7 @@ public class UserDirectoryPanel extends 
AnyDirectoryPanel<UserTO, UserRestClient
                     utilityModal.show(true);
                 }
             }, ActionType.PROPAGATION_TASKS, StandardEntitlement.TASK_LIST);
-            
+
             panel.add(new ActionLink<UserTO>() {
 
                 private static final long serialVersionUID = 
-7978723352517770644L;
@@ -343,6 +343,11 @@ public class UserDirectoryPanel extends 
AnyDirectoryPanel<UserTO, UserRestClient
                 }
                 ((BasePage) 
pageRef.getPage()).getNotificationPanel().refresh(target);
             }
+
+            @Override
+            protected boolean statusCondition(final UserTO modelObject) {
+                return realm.startsWith(SyncopeConstants.ROOT_REALM);
+            }
         }, ActionType.DELETE, StandardEntitlement.USER_DELETE, 
true).setRealm(realm);
 
         return panel;

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
index 7ffb5e6..3855d31 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/rest/RealmRestClient.java
@@ -18,11 +18,15 @@
  */
 package org.apache.syncope.client.console.rest;
 
+import static org.apache.syncope.client.console.rest.BaseRestClient.getService;
+
 import java.util.List;
 import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.DynRealmTO;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.syncope.common.rest.api.service.DynRealmService;
 import org.apache.syncope.common.rest.api.service.RealmService;
 
 /**
@@ -36,6 +40,14 @@ public class RealmRestClient extends BaseRestClient {
         return getService(RealmService.class).list();
     }
 
+    public List<DynRealmTO> listDynReams() {
+        return getService(DynRealmService.class).list();
+    }
+
+    public DynRealmTO readDynReams(final String key) {
+        return getService(DynRealmService.class).read(key);
+    }
+
     public ProvisioningResult<RealmTO> create(final String parentPath, final 
RealmTO realmTO) {
         final Response response = 
getService(RealmService.class).create(parentPath, realmTO);
         return response.readEntity(new 
GenericType<ProvisioningResult<RealmTO>>() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css 
b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
index da65a20..5b81fc2 100644
--- 
a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
+++ 
b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
@@ -1141,6 +1141,10 @@ ul.menu i {
   width: 35px;
 }
 
+div#inline-actions ul.menu i, div#tablehandling ul.menu i {
+  width: auto !important;
+}
+
 .toggle-menu ul.menu li a {
   padding: 0px;
   text-align: left;

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.properties
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.properties
 
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.properties
index a8eb7d5..4cfe42d 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.properties
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.properties
@@ -18,3 +18,7 @@ any.realm.new=New Realm
 any.realm.edit=Edit Realm ${fullPath}
 inner.template.edit=Edit ${left} template for '${right.fullPath}' 
 afterObj=Object Link
+realmLabel=Realm
+dynRealmLabel=Dynamic Realm
+realms=Realms
+dynrealms=Dynamic Realms

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_it.properties
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_it.properties
 
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_it.properties
index 8e84750..c2f149c 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_it.properties
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_it.properties
@@ -18,3 +18,7 @@ any.realm.new=New Realm
 any.realm.edit=Edit Realm ${fullPath}
 inner.template.edit=Modifica ${left} template per '${right.fullPath}' 
 afterObj=Object Link
+realmLabel=Realm
+dynRealmLabel=Realm Dinamico
+realms=Realm
+dynrealms=Realm Dinamici

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_pt_BR.properties
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_pt_BR.properties
 
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_pt_BR.properties
index a8eb7d5..4cfe42d 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_pt_BR.properties
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_pt_BR.properties
@@ -18,3 +18,7 @@ any.realm.new=New Realm
 any.realm.edit=Edit Realm ${fullPath}
 inner.template.edit=Edit ${left} template for '${right.fullPath}' 
 afterObj=Object Link
+realmLabel=Realm
+dynRealmLabel=Dynamic Realm
+realms=Realms
+dynrealms=Dynamic Realms

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_ru.properties
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_ru.properties
 
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_ru.properties
index 4a84c39..d1d0260 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_ru.properties
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms_ru.properties
@@ -19,3 +19,7 @@ any.realm.new=\u0421\u043e\u0437\u0434\u0430\u0442\u044c 
\u043e\u0431\u043b\u043
 any.realm.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c 
\u043e\u0431\u043b\u0430\u0441\u0442\u044c ${fullPath}
 inner.template.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c ${left} 
\u0448\u0430\u0431\u043b\u043e\u043d \u0434\u043b\u044f '${right.fullPath}'
 afterObj=\u0421\u0432\u044f\u0437\u044c 
\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432
+realmLabel=Realm
+dynRealmLabel=Dynamic Realm
+realms=Realms
+dynrealms=Dynamic Realms

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html
 
b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html
index a918dac..9933477 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmChoicePanel.html
@@ -20,7 +20,7 @@ under the License.
   <wicket:panel>
     <div wicket:id="container" class="realm-header">
       <div class="realm-label">
-        Realm: <label wicket:id="realm"/>
+        <label wicket:id="realmLabel"/>: <label wicket:id="realm"/>
       </div>
       <div class="realm-choice">
         <button wicket:id="realms"></button>

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
index 0809a48..26eabdb 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
@@ -66,7 +66,7 @@ public class RealmsITCase extends AbstractConsoleITCase {
         TESTER.clickLink("body:realmsLI:realms");
 
         
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:btn", 
Constants.ON_CLICK);
-        
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:dropdown-menu:buttons:4:button",
+        
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:dropdown-menu:buttons:5:button",
                 Constants.ON_CLICK);
 
         TESTER.assertLabel("body:content:realmChoicePanel:container:realm", 
"/testRealm");
@@ -104,7 +104,7 @@ public class RealmsITCase extends AbstractConsoleITCase {
     @Test
     public void addUserTemplate() {
         
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:btn", 
Constants.ON_CLICK);
-        
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:dropdown-menu:buttons:3:button",
+        
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:dropdown-menu:buttons:4:button",
                 Constants.ON_CLICK);
 
         TESTER.assertLabel("body:content:realmChoicePanel:container:realm", 
"/odd");
@@ -154,7 +154,7 @@ public class RealmsITCase extends AbstractConsoleITCase {
     @Test
     public void verifyPropagation() {
         
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:btn", 
Constants.ON_CLICK);
-        
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:dropdown-menu:buttons:2:button",
+        
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:dropdown-menu:buttons:3:button",
                 Constants.ON_CLICK);
 
         TESTER.clickLink(

http://git-wip-us.apache.org/repos/asf/syncope/blob/65a0f14d/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
index efc690e..77d479e 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
@@ -164,7 +164,7 @@ public class UsersITCase extends AbstractConsoleITCase {
     public void editUserMembership() {
         TESTER.clickLink("body:realmsLI:realms");
         
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:btn", 
Constants.ON_CLICK);
-        
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:dropdown-menu:buttons:1:button",
+        
TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:dropdown-menu:buttons:2:button",
                 Constants.ON_CLICK);
 
         
TESTER.clickLink("body:content:body:container:content:tabbedPanel:tabs-container:tabs:1:link");

Reply via email to