syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject [25/27] syncope git commit: [SYNCOPE-119] Renaming Role to Group
Date Mon, 06 Apr 2015 16:14:21 GMT
http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDetailsPanel.java
new file mode 100644
index 0000000..4af9d25
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDetailsPanel.java
@@ -0,0 +1,435 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.JexlHelpUtil;
+import org.apache.syncope.client.console.pages.GroupSelectModalPage;
+import org.apache.syncope.client.console.pages.UserOwnerSelectModalPage;
+import org.apache.syncope.client.console.panels.AttrTemplatesPanel.GroupAttrTemplatesChange;
+import org.apache.syncope.client.console.panels.AttrTemplatesPanel.Type;
+import org.apache.syncope.client.console.rest.GroupRestClient;
+import org.apache.syncope.client.console.rest.UserRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.wicket.Page;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.panel.Fragment;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroupDetailsPanel extends Panel {
+
+    private static final long serialVersionUID = 855618618337931784L;
+
+    /**
+     * Logger.
+     */
+    protected static final Logger LOG = LoggerFactory.getLogger(GroupDetailsPanel.class);
+
+    @SpringBean
+    private UserRestClient userRestClient;
+
+    @SpringBean
+    private GroupRestClient groupRestClient;
+
+    private final Fragment parentFragment;
+
+    private final WebMarkupContainer ownerContainer;
+
+    private final OwnerModel userOwnerModel;
+
+    private final OwnerModel groupOwnerModel;
+
+    private ParentModel parentModel;
+
+    public GroupDetailsPanel(final String id, final GroupTO groupTO, final boolean templateMode) {
+        super(id);
+
+        ownerContainer = new WebMarkupContainer("ownerContainer");
+        ownerContainer.setOutputMarkupId(true);
+        this.add(ownerContainer);
+
+        final ModalWindow userOwnerSelectWin = new ModalWindow("userOwnerSelectWin");
+        userOwnerSelectWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        userOwnerSelectWin.setCookieName("create-userOwnerSelect-modal");
+        this.add(userOwnerSelectWin);
+        final ModalWindow groupOwnerSelectWin = new ModalWindow("groupOwnerSelectWin");
+        groupOwnerSelectWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        groupOwnerSelectWin.setCookieName("create-groupOwnerSelect-modal");
+        this.add(groupOwnerSelectWin);
+        final ModalWindow parentSelectWin = new ModalWindow("parentSelectWin");
+        parentSelectWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        parentSelectWin.setCookieName("create-parentSelect-modal");
+        this.add(parentSelectWin);
+
+        if (templateMode) {
+            parentFragment = new Fragment("parent", "parentFragment", this);
+
+            parentModel = new ParentModel(groupTO);
+            @SuppressWarnings("unchecked")
+            final AjaxTextFieldPanel parent = new AjaxTextFieldPanel("parent", "parent", parentModel);
+            parent.setReadOnly(true);
+            parent.setOutputMarkupId(true);
+            parentFragment.add(parent);
+            final AjaxLink<Void> parentSelect = new IndicatingAjaxLink<Void>("parentSelect") {
+
+                private static final long serialVersionUID = -7978723352517770644L;
+
+                @Override
+                public void onClick(final AjaxRequestTarget target) {
+                    parentSelectWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                        private static final long serialVersionUID = -7834632442532690940L;
+
+                        @Override
+                        public Page createPage() {
+                            return new GroupSelectModalPage(getPage().getPageReference(), parentSelectWin,
+                                    ParentSelectPayload.class);
+                        }
+                    });
+                    parentSelectWin.show(target);
+                }
+            };
+            parentFragment.add(parentSelect);
+            final IndicatingAjaxLink<Void> parentReset = new IndicatingAjaxLink<Void>("parentReset") {
+
+                private static final long serialVersionUID = -7978723352517770644L;
+
+                @Override
+                public void onClick(final AjaxRequestTarget target) {
+                    parentModel.setObject(null);
+                    target.add(parent);
+                }
+            };
+            parentFragment.add(parentReset);
+        } else {
+            parentFragment = new Fragment("parent", "emptyFragment", this);
+        }
+        parentFragment.setOutputMarkupId(true);
+        this.add(parentFragment);
+
+        final AjaxTextFieldPanel name =
+                new AjaxTextFieldPanel("name", "name", new PropertyModel<String>(groupTO, "key"));
+
+        final WebMarkupContainer jexlHelp = JexlHelpUtil.getJexlHelpWebContainer("jexlHelp");
+
+        final AjaxLink<Void> questionMarkJexlHelp = JexlHelpUtil.getAjaxLink(jexlHelp, "questionMarkJexlHelp");
+        this.add(questionMarkJexlHelp);
+        questionMarkJexlHelp.add(jexlHelp);
+
+        if (!templateMode) {
+            name.addRequiredLabel();
+            questionMarkJexlHelp.setVisible(false);
+        }
+        this.add(name);
+
+        userOwnerModel = new OwnerModel(groupTO, AttributableType.USER);
+        @SuppressWarnings("unchecked")
+        final AjaxTextFieldPanel userOwner = new AjaxTextFieldPanel("userOwner", "userOwner", userOwnerModel);
+        userOwner.setReadOnly(true);
+        userOwner.setOutputMarkupId(true);
+        ownerContainer.add(userOwner);
+        final AjaxLink<Void> userOwnerSelect = new IndicatingAjaxLink<Void>("userOwnerSelect") {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                userOwnerSelectWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                    private static final long serialVersionUID = -7834632442532690940L;
+
+                    @Override
+                    public Page createPage() {
+                        return new UserOwnerSelectModalPage(getPage().getPageReference(), userOwnerSelectWin);
+                    }
+                });
+                userOwnerSelectWin.show(target);
+            }
+        };
+        ownerContainer.add(userOwnerSelect);
+        final IndicatingAjaxLink<Void> userOwnerReset = new IndicatingAjaxLink<Void>("userOwnerReset") {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                userOwnerModel.setObject(null);
+                target.add(userOwner);
+            }
+        };
+        ownerContainer.add(userOwnerReset);
+
+        groupOwnerModel = new OwnerModel(groupTO, AttributableType.GROUP);
+        @SuppressWarnings("unchecked")
+        final AjaxTextFieldPanel groupOwner = new AjaxTextFieldPanel("groupOwner", "groupOwner", groupOwnerModel);
+        groupOwner.setReadOnly(true);
+        groupOwner.setOutputMarkupId(true);
+        ownerContainer.add(groupOwner);
+        final AjaxLink<Void> groupOwnerSelect = new IndicatingAjaxLink<Void>("groupOwnerSelect") {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                parentSelectWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                    private static final long serialVersionUID = -7834632442532690940L;
+
+                    @Override
+                    public Page createPage() {
+                        return new GroupSelectModalPage(getPage().getPageReference(), parentSelectWin,
+                                GroupOwnerSelectPayload.class);
+                    }
+                });
+                parentSelectWin.show(target);
+            }
+        };
+        ownerContainer.add(groupOwnerSelect);
+        final IndicatingAjaxLink<Void> groupOwnerReset = new IndicatingAjaxLink<Void>("groupOwnerReset") {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                groupOwnerModel.setObject(null);
+                target.add(groupOwner);
+            }
+        };
+        ownerContainer.add(groupOwnerReset);
+
+        final AjaxCheckBoxPanel inhOwner = new AjaxCheckBoxPanel("inheritOwner", "inheritOwner",
+                new PropertyModel<Boolean>(groupTO, "inheritOwner"));
+        this.add(inhOwner);
+
+        final AjaxCheckBoxPanel inhTemplates = new AjaxCheckBoxPanel("inheritTemplates", "inheritTemplates",
+                new PropertyModel<Boolean>(groupTO, "inheritTemplates"));
+        inhTemplates.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                send(getPage(), Broadcast.BREADTH, new GroupAttrTemplatesChange(Type.gPlainAttrTemplates, target));
+                send(getPage(), Broadcast.BREADTH, new GroupAttrTemplatesChange(Type.gDerAttrTemplates, target));
+                send(getPage(), Broadcast.BREADTH, new GroupAttrTemplatesChange(Type.gVirAttrTemplates, target));
+            }
+        });
+        this.add(inhTemplates);
+    }
+
+    /**
+     * This is waiting for events from opened modal windows: first to get the selected user / group, then to update the
+     * respective text panel.
+     *
+     * {@inheritDoc }
+     */
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        super.onEvent(event);
+
+        if (event.getPayload() instanceof ParentSelectPayload) {
+            parentModel.setObject(((ParentSelectPayload) event.getPayload()).getGroupId());
+        }
+        if (event.getPayload() instanceof UserOwnerSelectPayload) {
+            userOwnerModel.setObject(((UserOwnerSelectPayload) event.getPayload()).getUserId());
+        }
+        if (event.getPayload() instanceof GroupOwnerSelectPayload) {
+            groupOwnerModel.setObject(((GroupOwnerSelectPayload) event.getPayload()).getGroupId());
+        }
+
+        if (event.getPayload() instanceof AjaxRequestTarget) {
+            ((AjaxRequestTarget) event.getPayload()).add(parentFragment);
+            ((AjaxRequestTarget) event.getPayload()).add(ownerContainer);
+        }
+    }
+
+    private class OwnerModel implements IModel {
+
+        private static final long serialVersionUID = -3865621970810102714L;
+
+        private final GroupTO groupTO;
+
+        private final AttributableType type;
+
+        public OwnerModel(final GroupTO groupTO, final AttributableType type) {
+            this.groupTO = groupTO;
+            this.type = type;
+        }
+
+        @Override
+        public Object getObject() {
+            String object = null;
+
+            switch (type) {
+                case USER:
+                    if (groupTO.getUserOwner() != null) {
+                        UserTO user = null;
+                        try {
+                            user = userRestClient.read(groupTO.getUserOwner());
+                        } catch (Exception e) {
+                            LOG.warn("Could not find user with id {}, ignoring", groupTO.getUserOwner(), e);
+                        }
+                        if (user == null) {
+                            groupTO.setUserOwner(null);
+                        } else {
+                            object = user.getKey() + " " + user.getUsername();
+                        }
+                    }
+                    break;
+
+                case GROUP:
+                    GroupTO group = null;
+                    if (groupTO.getGroupOwner() != null) {
+                        try {
+                            group = groupRestClient.read(groupTO.getGroupOwner());
+                        } catch (Exception e) {
+                            LOG.warn("Could not find group with id {}, ignoring", groupTO.getGroupOwner(), e);
+                        }
+                        if (group == null) {
+                            groupTO.setGroupOwner(null);
+                        } else {
+                            object = group.getDisplayName();
+                        }
+                    }
+                    break;
+
+                case MEMBERSHIP:
+                default:
+            }
+
+            return object;
+        }
+
+        @Override
+        public void setObject(final Object object) {
+            switch (type) {
+                case USER:
+                    groupTO.setUserOwner((Long) object);
+                    break;
+
+                case GROUP:
+                    groupTO.setGroupOwner((Long) object);
+                    break;
+
+                case MEMBERSHIP:
+                default:
+            }
+        }
+
+        @Override
+        public void detach() {
+            // ignore
+        }
+    }
+
+    private class ParentModel implements IModel {
+
+        private static final long serialVersionUID = 1006546156848990721L;
+
+        private final GroupTO groupTO;
+
+        public ParentModel(final GroupTO groupTO) {
+            this.groupTO = groupTO;
+        }
+
+        @Override
+        public Object getObject() {
+            Object object = null;
+            if (groupTO.getParent() != 0) {
+                GroupTO parent = null;
+                try {
+                    parent = groupRestClient.read(groupTO.getParent());
+                } catch (Exception e) {
+                    LOG.warn("Could not find group with id {}, ignoring", groupTO.getParent(), e);
+                }
+                if (parent == null) {
+                    groupTO.setParent(0);
+                } else {
+                    object = parent.getDisplayName();
+                }
+            }
+            return object;
+        }
+
+        @Override
+        public void setObject(final Object object) {
+            groupTO.setParent((object instanceof Long) ? ((Long) object) : 0);
+        }
+
+        @Override
+        public void detach() {
+            // ignore
+        }
+    }
+
+    public static class UserOwnerSelectPayload {
+
+        private final Long userId;
+
+        public UserOwnerSelectPayload(final Long userId) {
+            this.userId = userId;
+        }
+
+        public Long getUserId() {
+            return userId;
+        }
+    }
+
+    public static class GroupOwnerSelectPayload {
+
+        private final Long groupId;
+
+        public GroupOwnerSelectPayload(final Long groupId) {
+            this.groupId = groupId;
+        }
+
+        public Long getGroupId() {
+            return groupId;
+        }
+    }
+
+    public static class ParentSelectPayload {
+
+        private final Long groupId;
+
+        public ParentSelectPayload(final Long groupId) {
+            this.groupId = groupId;
+        }
+
+        public Long getGroupId() {
+            return groupId;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupPanel.java
new file mode 100644
index 0000000..7cbf47e
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupPanel.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.client.console.commons.Mode;
+import org.apache.syncope.client.console.commons.XMLRolesReader;
+import org.apache.syncope.client.console.commons.status.StatusBean;
+import org.apache.syncope.client.console.rest.AuthRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.util.ListModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public class GroupPanel extends Panel {
+
+    private static final long serialVersionUID = 4216376097320768369L;
+
+    @SpringBean
+    private AuthRestClient authRestClient;
+
+    @SpringBean
+    private XMLRolesReader xmlRolesReader;
+
+    private final AjaxPalettePanel<String> entitlements;
+
+    public static class Builder implements Serializable {
+
+        private static final long serialVersionUID = 8150440254654306070L;
+
+        private String id;
+
+        private Form form;
+
+        private GroupTO groupTO;
+
+        private Mode mode;
+
+        private PageReference pageReference;
+
+        public Builder(final String id) {
+            this.id = id;
+        }
+
+        public Builder form(final Form form) {
+            this.form = form;
+            return this;
+        }
+
+        public Builder groupTO(final GroupTO groupTO) {
+            this.groupTO = groupTO;
+            return this;
+        }
+
+        public Builder groupModalPageMode(final Mode mode) {
+            this.mode = mode;
+            return this;
+        }
+
+        public Builder pageRef(final PageReference pageReference) {
+            this.pageReference = pageReference;
+            return this;
+        }
+
+        public GroupPanel build() {
+            return new GroupPanel(this);
+        }
+    }
+
+    private GroupPanel(final Builder builder) {
+        super(builder.id);
+
+        this.add(new GroupDetailsPanel("details", builder.groupTO, builder.mode == Mode.TEMPLATE));
+
+        if (builder.pageReference == null || builder.groupTO.getKey() == 0) {
+            this.add(new Label("statuspanel", ""));
+        } else {
+            StatusPanel statusPanel = new StatusPanel(
+                    "statuspanel", builder.groupTO, new ArrayList<StatusBean>(), builder.pageReference);
+            statusPanel.setOutputMarkupId(true);
+            MetaDataRoleAuthorizationStrategy.authorize(
+                    statusPanel, RENDER, xmlRolesReader.getEntitlement("Resources", "getConnectorObject"));
+            this.add(statusPanel);
+        }
+
+        this.add(new AnnotatedBeanPanel("systeminformation", builder.groupTO));
+
+        //--------------------------------
+        // Attribute templates panel
+        //--------------------------------
+        AttrTemplatesPanel attrTemplates = new AttrTemplatesPanel("templates", builder.groupTO);
+        this.add(attrTemplates);
+
+        //--------------------------------
+        // Attributes panel
+        //--------------------------------
+        this.add(new PlainAttrsPanel(
+                "plainAttrs", builder.groupTO, builder.form, builder.mode, attrTemplates));
+
+        final AjaxCheckBoxPanel inhAttributes = new AjaxCheckBoxPanel("inheritPlainAttrs", "inheritPlainAttrs",
+                new PropertyModel<Boolean>(builder.groupTO, "inheritPlainAttrs"));
+        inhAttributes.setOutputMarkupId(true);
+        this.add(inhAttributes);
+        //--------------------------------
+
+        //--------------------------------
+        // Derived attributes panel
+        //--------------------------------
+        this.add(new DerAttrsPanel("derAttrs", builder.groupTO, attrTemplates));
+
+        final AjaxCheckBoxPanel inhDerivedAttributes = new AjaxCheckBoxPanel("inheritDerAttrs",
+                "inheritDerAttrs", new PropertyModel<Boolean>(builder.groupTO, "inheritDerAttrs"));
+        inhDerivedAttributes.setOutputMarkupId(true);
+        this.add(inhDerivedAttributes);
+        //--------------------------------
+
+        //--------------------------------
+        // Virtual attributes panel
+        //--------------------------------
+        this.add(new VirAttrsPanel(
+                "virAttrs", builder.groupTO, builder.mode == Mode.TEMPLATE, attrTemplates));
+
+        final AjaxCheckBoxPanel inhVirtualAttributes = new AjaxCheckBoxPanel("inheritVirAttrs",
+                "inheritVirAttrs", new PropertyModel<Boolean>(builder.groupTO, "inheritVirAttrs"));
+        inhVirtualAttributes.setOutputMarkupId(true);
+        this.add(inhVirtualAttributes);
+        //--------------------------------
+
+        //--------------------------------
+        // Resources panel
+        //--------------------------------
+        this.add(new ResourcesPanel.Builder("resources").attributableTO(builder.groupTO).build().
+                setOutputMarkupId(true));
+        //--------------------------------
+
+        //--------------------------------
+        // Entitlements
+        //--------------------------------
+        ListModel<String> selectedEntitlements = new ListModel<String>(builder.groupTO.getEntitlements());
+
+        List<String> allEntitlements = authRestClient.getAllEntitlements();
+        if (allEntitlements != null && !allEntitlements.isEmpty()) {
+            Collections.sort(allEntitlements);
+        }
+        ListModel<String> availableEntitlements = new ListModel<String>(allEntitlements);
+
+        entitlements = new AjaxPalettePanel<String>("entitlements", selectedEntitlements, availableEntitlements);
+        this.add(entitlements);
+
+        //--------------------------------
+        // Security panel
+        //--------------------------------
+        this.add(new GroupSecurityPanel("security", builder.groupTO).setOutputMarkupId(true));
+        //--------------------------------
+    }
+
+    public Collection<String> getSelectedEntitlements() {
+        return this.entitlements.getModelCollection();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchPanel.java
new file mode 100644
index 0000000..d13ab94
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchPanel.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.wicket.model.LoadableDetachableModel;
+
+public class GroupSearchPanel extends AbstractSearchPanel {
+
+    private static final long serialVersionUID = 5757183539269316263L;
+
+    public static class Builder implements Serializable {
+
+        private static final long serialVersionUID = 6308997285778809579L;
+
+        private String id;
+
+        private String fiql = null;
+
+        private boolean required = true;
+
+        public Builder(final String id) {
+            this.id = id;
+        }
+
+        public Builder fiql(final String fiql) {
+            this.fiql = fiql;
+            return this;
+        }
+
+        public Builder required(final boolean required) {
+            this.required = required;
+            return this;
+        }
+
+        public GroupSearchPanel build() {
+            return new GroupSearchPanel(this);
+        }
+    }
+
+    private GroupSearchPanel(final Builder builder) {
+        super(builder.id, AttributableType.GROUP, builder.fiql, builder.required);
+    }
+
+    @Override
+    protected void populate() {
+        super.populate();
+
+        this.types = new LoadableDetachableModel<List<SearchClause.Type>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected List<SearchClause.Type> load() {
+                final List<SearchClause.Type> result = new ArrayList<SearchClause.Type>();
+                result.add(SearchClause.Type.ATTRIBUTE);
+                result.add(SearchClause.Type.ENTITLEMENT);
+                result.add(SearchClause.Type.RESOURCE);
+                return result;
+            }
+        };
+
+        this.groupNames = new LoadableDetachableModel<List<String>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected List<String> load() {
+                return Collections.<String>emptyList();
+            }
+        };
+    }
+
+    @Override
+    protected AbstractFiqlSearchConditionBuilder getSearchConditionBuilder() {
+        return SyncopeClient.getGroupSearchConditionBuilder();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
new file mode 100644
index 0000000..a7dac82
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSearchResultPanel.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.pages.ResultStatusModalPage;
+import org.apache.syncope.client.console.pages.GroupModalPage;
+import org.apache.syncope.client.console.pages.StatusModalPage;
+import org.apache.syncope.client.console.rest.AbstractSubjectRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.ResourceModel;
+
+public class GroupSearchResultPanel extends AbstractSearchResultPanel {
+
+    private static final long serialVersionUID = -1180593361914008764L;
+
+    private final static String PAGEID = "Groups";
+
+    public <T extends AbstractAttributableTO> GroupSearchResultPanel(final String id, final boolean filtered,
+            final String fiql, final PageReference callerRef, final AbstractSubjectRestClient restClient) {
+
+        super(id, filtered, fiql, callerRef, restClient);
+        initResultTable();
+    }
+
+    @Override
+    protected List<IColumn<AbstractAttributableTO, String>> getColumns() {
+        final List<IColumn<AbstractAttributableTO, String>> columns = new ArrayList<>();
+
+        for (String item : new String[] { "key", "name", "entitlements" }) {
+            columns.add(new PropertyColumn<AbstractAttributableTO, String>(new ResourceModel(item, item), item, item));
+        }
+
+        columns.add(new AbstractColumn<AbstractAttributableTO, String>(new ResourceModel("actions", "")) {
+
+            private static final long serialVersionUID = -3503023501954863131L;
+
+            @Override
+            public String getCssClass() {
+                return "action";
+            }
+
+            @Override
+            public void populateItem(final Item<ICellPopulator<AbstractAttributableTO>> cellItem,
+                    final String componentId, final IModel<AbstractAttributableTO> model) {
+
+                final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, page.getPageReference());
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        statusmodal.setPageCreator(new ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = -7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                return new StatusModalPage<GroupTO>(
+                                        page.getPageReference(), statusmodal, (GroupTO) model.getObject());
+                            }
+                        });
+
+                        statusmodal.show(target);
+                    }
+                }, ActionLink.ActionType.MANAGE_RESOURCES, PAGEID);
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        editmodal.setPageCreator(new ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = -7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                return new GroupModalPage(
+                                        page.getPageReference(), editmodal, (GroupTO) model.getObject());
+                            }
+                        });
+
+                        editmodal.show(target);
+                    }
+                }, ActionLink.ActionType.EDIT, PAGEID);
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        try {
+                            final GroupTO groupTO = (GroupTO) restClient.
+                                    delete(model.getObject().getETagValue(), model.getObject().getKey());
+
+                            page.setModalResult(true);
+
+                            editmodal.setPageCreator(new ModalWindow.PageCreator() {
+
+                                private static final long serialVersionUID = -7834632442532690940L;
+
+                                @Override
+                                public Page createPage() {
+                                    return new ResultStatusModalPage.Builder(editmodal, groupTO).build();
+                                }
+                            });
+
+                            editmodal.show(target);
+                        } catch (SyncopeClientException scce) {
+                            error(getString(Constants.OPERATION_ERROR) + ": " + scce.getMessage());
+                            feedbackPanel.refresh(target);
+                        }
+                    }
+                }, ActionLink.ActionType.DELETE, PAGEID);
+
+                cellItem.add(panel);
+            }
+        });
+
+        return columns;
+    }
+
+    @Override
+    protected Collection<ActionType> getBulkActions() {
+        return Collections.<ActionLink.ActionType>singletonList(ActionLink.ActionType.DELETE);
+    }
+
+    @Override
+    protected String getPageId() {
+        return PAGEID;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSecurityPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSecurityPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSecurityPanel.java
new file mode 100644
index 0000000..4e0e1f9
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSecurityPanel.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.PolicyRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AbstractPolicyTO;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.ChoiceRenderer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroupSecurityPanel extends Panel {
+
+    /**
+     * Logger.
+     */
+    protected static final Logger LOG = LoggerFactory.getLogger(GroupSecurityPanel.class);
+
+    private static final long serialVersionUID = -7982691107029848579L;
+
+    @SpringBean
+    private PolicyRestClient policyRestClient;
+
+    private IModel<Map<Long, String>> passwordPolicies = null;
+
+    private IModel<Map<Long, String>> accountPolicies = null;
+
+    public <T extends AbstractAttributableTO> GroupSecurityPanel(final String id, final T entityTO) {
+        super(id);
+
+        setOutputMarkupId(true);
+
+        passwordPolicies = new LoadableDetachableModel<Map<Long, String>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected Map<Long, String> load() {
+                Map<Long, String> res = new HashMap<>();
+                for (AbstractPolicyTO policyTO : policyRestClient.getPolicies(PolicyType.PASSWORD, false)) {
+                    res.put(policyTO.getKey(), policyTO.getDescription());
+                }
+                return res;
+            }
+        };
+
+        accountPolicies = new LoadableDetachableModel<Map<Long, String>>() {
+
+            private static final long serialVersionUID = -2012833443695917883L;
+
+            @Override
+            protected Map<Long, String> load() {
+                Map<Long, String> res = new HashMap<>();
+                for (AbstractPolicyTO policyTO : policyRestClient.getPolicies(PolicyType.ACCOUNT, false)) {
+                    res.put(policyTO.getKey(), policyTO.getDescription());
+                }
+                return res;
+            }
+        };
+
+        final WebMarkupContainer securityContainer = new WebMarkupContainer("security");
+
+        securityContainer.setOutputMarkupId(true);
+        add(securityContainer);
+
+        // -------------------------------
+        // Password policy specification
+        // -------------------------------
+        final AjaxDropDownChoicePanel<Long> passwordPolicy = new AjaxDropDownChoicePanel<Long>("passwordPolicy",
+                "passwordPolicy", new PropertyModel<Long>(entityTO, "passwordPolicy"));
+
+        passwordPolicy.setChoiceRenderer(new PolicyRenderer(PolicyType.PASSWORD));
+
+        passwordPolicy.setChoices(new ArrayList<Long>(passwordPolicies.getObject().keySet()));
+
+        ((DropDownChoice<?>) passwordPolicy.getField()).setNullValid(true);
+
+        securityContainer.add(passwordPolicy);
+
+        final AjaxCheckBoxPanel inhPasswordPolicy = new AjaxCheckBoxPanel("inheritPasswordPolicy",
+                "inheritPasswordPolicy", new PropertyModel<Boolean>(entityTO, "inheritPasswordPolicy"));
+
+        passwordPolicy.setReadOnly(inhPasswordPolicy.getModelObject());
+
+        inhPasswordPolicy.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                passwordPolicy.setReadOnly(inhPasswordPolicy.getModelObject());
+                target.add(passwordPolicy);
+            }
+        });
+
+        securityContainer.add(inhPasswordPolicy);
+        // -------------------------------
+
+        // -------------------------------
+        // Account policy specification
+        // -------------------------------
+        final AjaxDropDownChoicePanel<Long> accountPolicy = new AjaxDropDownChoicePanel<Long>("accountPolicy",
+                "accountPolicy", new PropertyModel<Long>(entityTO, "accountPolicy"));
+
+        accountPolicy.setChoiceRenderer(new PolicyRenderer(PolicyType.ACCOUNT));
+
+        accountPolicy.setChoices(new ArrayList<Long>(accountPolicies.getObject().keySet()));
+
+        ((DropDownChoice<?>) accountPolicy.getField()).setNullValid(true);
+
+        securityContainer.add(accountPolicy);
+
+        final AjaxCheckBoxPanel inhAccountPolicy = new AjaxCheckBoxPanel("inheritAccountPolicy",
+                "inheritAccountPolicy", new PropertyModel<Boolean>(entityTO, "inheritAccountPolicy"));
+        accountPolicy.setReadOnly(inhAccountPolicy.getModelObject());
+
+        inhAccountPolicy.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                accountPolicy.setReadOnly(inhAccountPolicy.getModelObject());
+                target.add(accountPolicy);
+            }
+        });
+
+        securityContainer.add(inhAccountPolicy);
+        // -------------------------------
+    }
+
+    private class PolicyRenderer extends ChoiceRenderer<Long> {
+
+        private static final long serialVersionUID = 8060500161321947000L;
+
+        private PolicyType type;
+
+        public PolicyRenderer(final PolicyType type) {
+            super();
+            this.type = type;
+        }
+
+        @Override
+        public Object getDisplayValue(final Long object) {
+            Object displayValue;
+            switch (type) {
+                case ACCOUNT:
+                    displayValue = accountPolicies.getObject().get(object);
+                    break;
+                case PASSWORD:
+                    displayValue = passwordPolicies.getObject().get(object);
+                    break;
+                default:
+                    displayValue = "";
+            }
+            return displayValue;
+        }
+
+        @Override
+        public String getIdValue(Long object, int index) {
+            return String.valueOf(object != null
+                    ? object
+                    : 0L);
+        }
+    };
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSummaryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSummaryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSummaryPanel.java
new file mode 100644
index 0000000..f9a56e6
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupSummaryPanel.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.io.Serializable;
+import org.apache.syncope.client.console.commons.XMLRolesReader;
+import org.apache.syncope.client.console.pages.GroupModalPage;
+import org.apache.syncope.client.console.rest.GroupRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.panel.Fragment;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroupSummaryPanel extends Panel {
+
+    private static final long serialVersionUID = 643769814985593156L;
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(GroupSummaryPanel.class);
+
+    @SpringBean
+    private XMLRolesReader xmlRolesReader;
+
+    @SpringBean
+    private GroupRestClient restClient;
+
+    private GroupTO selectedNode;
+
+    public static class Builder implements Serializable {
+
+        private static final long serialVersionUID = 4164563358509351832L;
+
+        private String id;
+
+        private ModalWindow window;
+
+        private PageReference callerPageRef;
+
+        private Long selectedNodeId = null;
+
+        public Builder(final String id) {
+            this.id = id;
+        }
+
+        public GroupSummaryPanel.Builder window(final ModalWindow window) {
+            this.window = window;
+            return this;
+        }
+
+        public GroupSummaryPanel.Builder callerPageRef(final PageReference callerPageRef) {
+            this.callerPageRef = callerPageRef;
+            return this;
+        }
+
+        public GroupSummaryPanel.Builder selectedNodeId(final Long selectedNodeId) {
+            this.selectedNodeId = selectedNodeId;
+            return this;
+        }
+
+        public GroupSummaryPanel build() {
+            return new GroupSummaryPanel(this);
+        }
+    }
+
+    private GroupSummaryPanel(final Builder builder) {
+        super(builder.id);
+
+        if (builder.selectedNodeId == null || builder.selectedNodeId == 0) {
+            selectedNode = null;
+        } else {
+            try {
+                selectedNode = restClient.read(builder.selectedNodeId);
+            } catch (SyncopeClientException e) {
+                LOG.error("Could not read {}", builder.selectedNodeId, e);
+                selectedNode = null;
+                builder.selectedNodeId = null;
+            }
+        }
+
+        Fragment fragment = new Fragment("groupSummaryPanel",
+                builder.selectedNodeId == null
+                        ? "fakerootFrag"
+                        : (builder.selectedNodeId == 0 ? "rootPanel" : "groupViewPanel"),
+                this);
+
+        if (builder.selectedNodeId != null) {
+            if (builder.selectedNodeId == 0) {
+                @SuppressWarnings("rawtypes")
+                final ActionLinksPanel links = new ActionLinksPanel("actionLinks", new Model(), builder.callerPageRef);
+                links.setOutputMarkupId(true);
+                fragment.add(links);
+
+                links.addWithRoles(new ActionLink() {
+
+                    private static final long serialVersionUID = -3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        builder.window.setPageCreator(new ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = -7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                return new GroupModalPage(builder.callerPageRef, builder.window, new GroupTO());
+                            }
+                        });
+
+                        builder.window.show(target);
+                    }
+                }, ActionLink.ActionType.CREATE, xmlRolesReader.getEntitlement("Groups", "create"));
+            } else {
+                GroupTabPanel groupTabPanel =
+                        new GroupTabPanel("nodeViewPanel", selectedNode, builder.window, builder.callerPageRef);
+                groupTabPanel.setOutputMarkupId(true);
+                fragment.add(groupTabPanel);
+            }
+        }
+        add(fragment);
+    }
+
+    public GroupTO getSelectedNode() {
+        return selectedNode;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupTabPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupTabPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupTabPanel.java
new file mode 100644
index 0000000..9615554
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupTabPanel.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.Mode;
+import org.apache.syncope.client.console.commons.XMLRolesReader;
+import org.apache.syncope.client.console.pages.ResultStatusModalPage;
+import org.apache.syncope.client.console.pages.GroupModalPage;
+import org.apache.syncope.client.console.pages.Groups;
+import org.apache.syncope.client.console.pages.StatusModalPage;
+import org.apache.syncope.client.console.rest.GroupRestClient;
+import org.apache.syncope.client.console.rest.UserRestClient;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public class GroupTabPanel extends Panel {
+
+    private static final long serialVersionUID = 859236186975983959L;
+
+    @SpringBean
+    private XMLRolesReader xmlRolesReader;
+
+    @SpringBean
+    private GroupRestClient groupRestClient;
+
+    @SpringBean
+    private UserRestClient userRestClient;
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public GroupTabPanel(final String id, final GroupTO selectedNode, final ModalWindow window,
+            final PageReference pageRef) {
+
+        super(id);
+
+        this.add(new Label("displayName", selectedNode.getDisplayName()));
+
+        final ActionLinksPanel links = new ActionLinksPanel("actionLinks", new Model(), pageRef);
+        links.setOutputMarkupId(true);
+        this.add(links);
+        links.addWithRoles(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                window.setPageCreator(new ModalWindow.PageCreator() {
+
+                    private static final long serialVersionUID = -7834632442532690940L;
+
+                    @Override
+                    public Page createPage() {
+                        GroupTO groupTO = new GroupTO();
+                        groupTO.setParent(selectedNode.getKey());
+                        return new GroupModalPage(pageRef, window, groupTO);
+                    }
+                });
+
+                window.show(target);
+            }
+        }, ActionLink.ActionType.CREATE, xmlRolesReader.getEntitlement("Groups", "create"));
+        links.addWithRoles(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                window.setPageCreator(new ModalWindow.PageCreator() {
+
+                    private static final long serialVersionUID = -7834632442532690940L;
+
+                    @Override
+                    public Page createPage() {
+                        return new StatusModalPage<GroupTO>(pageRef, window, groupRestClient.read(selectedNode.getKey()));
+                    }
+                });
+
+                window.show(target);
+            }
+        }, ActionLink.ActionType.MANAGE_RESOURCES, xmlRolesReader.getEntitlement("Groups", "update"));
+        links.addWithRoles(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                window.setPageCreator(new ModalWindow.PageCreator() {
+
+                    private static final long serialVersionUID = -7834632442532690940L;
+
+                    @Override
+                    public Page createPage() {
+                        GroupTO groupTO = groupRestClient.read(selectedNode.getKey());
+                        return new GroupModalPage(pageRef, window, groupTO);
+                    }
+                });
+
+                window.show(target);
+            }
+        }, ActionLink.ActionType.EDIT, xmlRolesReader.getEntitlement("Groups", "update"));
+        links.addWithRoles(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                try {
+                    final GroupTO groupTO = groupRestClient.delete(selectedNode.getETagValue(), selectedNode.getKey());
+
+                    ((Groups) pageRef.getPage()).setModalResult(true);
+
+                    window.setPageCreator(new ModalWindow.PageCreator() {
+
+                        private static final long serialVersionUID = -7834632442532690940L;
+
+                        @Override
+                        public Page createPage() {
+                            return new ResultStatusModalPage.Builder(window, groupTO).build();
+                        }
+                    });
+
+                    window.show(target);
+                } catch (SyncopeClientException e) {
+                    error(getString(Constants.OPERATION_ERROR) + ": " + e.getMessage());
+                    ((Groups) pageRef.getPage()).getFeedbackPanel().refresh(target);
+                }
+            }
+        }, ActionLink.ActionType.DELETE, xmlRolesReader.getEntitlement("Groups", "delete"));
+
+        final Form form = new Form("groupForm");
+        form.setModel(new CompoundPropertyModel(selectedNode));
+        form.setOutputMarkupId(true);
+
+        final GroupPanel groupPanel = new GroupPanel.Builder("groupPanel").
+                form(form).groupTO(selectedNode).groupModalPageMode(Mode.ADMIN).build();
+        groupPanel.setEnabled(false);
+        form.add(groupPanel);
+
+        final WebMarkupContainer userListContainer = new WebMarkupContainer("userListContainer");
+
+        userListContainer.setOutputMarkupId(true);
+        userListContainer.setEnabled(true);
+        userListContainer.add(new UserSearchResultPanel("userList", true, null, pageRef, userRestClient));
+        userListContainer.add(new ClearIndicatingAjaxButton("search", new ResourceModel("search"), pageRef) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) {
+                userListContainer.replace(new UserSearchResultPanel("userList",
+                        true,
+                        SyncopeClient.getUserSearchConditionBuilder().inGroups(selectedNode.getKey()).query(),
+                        pageRef,
+                        userRestClient));
+
+                target.add(userListContainer);
+            }
+        });
+
+        form.add(userListContainer);
+        add(form);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/MembershipsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/MembershipsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/MembershipsPanel.java
index fb00dcf..9136462 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/MembershipsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/MembershipsPanel.java
@@ -24,8 +24,7 @@ import java.util.List;
 import java.util.Set;
 import javax.swing.tree.DefaultMutableTreeNode;
 import org.apache.syncope.client.console.commons.Mode;
-import org.apache.syncope.client.console.commons.RoleTreeBuilder;
-import org.apache.syncope.client.console.commons.RoleUtils;
+import org.apache.syncope.client.console.commons.GroupTreeBuilder;
 import org.apache.syncope.client.console.commons.status.StatusUtils;
 import org.apache.syncope.client.console.pages.MembershipModalPage;
 import org.apache.syncope.client.console.pages.UserModalPage;
@@ -33,9 +32,9 @@ import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicating
 import org.apache.syncope.client.console.wicket.ajax.markup.html.IndicatingOnConfirmAjaxLink;
 import org.apache.syncope.client.console.wicket.markup.html.tree.DefaultMutableTreeNodeExpansion;
 import org.apache.syncope.client.console.wicket.markup.html.tree.DefaultMutableTreeNodeExpansionModel;
-import org.apache.syncope.client.console.wicket.markup.html.tree.TreeRoleProvider;
+import org.apache.syncope.client.console.wicket.markup.html.tree.TreeGroupProvider;
 import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.Component;
 import org.apache.wicket.Page;
@@ -63,7 +62,7 @@ public class MembershipsPanel extends Panel {
     private static final long serialVersionUID = -2559791301973107191L;
 
     @SpringBean
-    private RoleTreeBuilder roleTreeBuilder;
+    private GroupTreeBuilder groupTreeBuilder;
 
     private final ListView<MembershipTO> membView;
 
@@ -89,7 +88,7 @@ public class MembershipsPanel extends Panel {
         membWin.setCookieName("create-membership-modal");
         add(membWin);
 
-        final ITreeProvider<DefaultMutableTreeNode> treeProvider = new TreeRoleProvider(roleTreeBuilder, true);
+        final ITreeProvider<DefaultMutableTreeNode> treeProvider = new TreeGroupProvider(groupTreeBuilder, true);
         final DefaultMutableTreeNodeExpansionModel treeModel = new DefaultMutableTreeNodeExpansionModel();
 
         tree = new DefaultNestedTree<DefaultMutableTreeNode>("treeTable", treeProvider, treeModel) {
@@ -99,7 +98,7 @@ public class MembershipsPanel extends Panel {
             @Override
             protected Component newContentComponent(final String id, final IModel<DefaultMutableTreeNode> node) {
                 final DefaultMutableTreeNode treeNode = node.getObject();
-                final RoleTO roleTO = (RoleTO) treeNode.getUserObject();
+                final GroupTO groupTO = (GroupTO) treeNode.getUserObject();
 
                 return new Folder<DefaultMutableTreeNode>(id, MembershipsPanel.this.tree, node) {
 
@@ -112,12 +111,12 @@ public class MembershipsPanel extends Panel {
 
                     @Override
                     protected IModel<?> newLabelModel(final IModel<DefaultMutableTreeNode> model) {
-                        return new Model<String>(roleTO.getDisplayName());
+                        return new Model<String>(groupTO.getDisplayName());
                     }
 
                     @Override
                     protected void onClick(final AjaxRequestTarget target) {
-                        if (roleTO.getKey() > 0) {
+                        if (groupTO.getKey() > 0) {
                             membWin.setPageCreator(new ModalWindow.PageCreator() {
 
                                 private static final long serialVersionUID = 7661763358801821185L;
@@ -127,13 +126,13 @@ public class MembershipsPanel extends Panel {
                                     PageReference pageRef = getPage().getPageReference();
 
                                     for (MembershipTO membTO : membView.getList()) {
-                                        if (membTO.getRoleId() == roleTO.getKey()) {
+                                        if (membTO.getGroupId() == groupTO.getKey()) {
                                             return new MembershipModalPage(pageRef, membWin, membTO, mode);
                                         }
                                     }
                                     MembershipTO membTO = new MembershipTO();
-                                    membTO.setRoleId(roleTO.getKey());
-                                    membTO.setRoleName(roleTO.getName());
+                                    membTO.setGroupId(groupTO.getKey());
+                                    membTO.setGroupName(groupTO.getName());
 
                                     return new MembershipModalPage(pageRef, membWin, membTO, mode);
                                 }
@@ -160,8 +159,8 @@ public class MembershipsPanel extends Panel {
                     protected void populateItem(final ListItem<MembershipTO> item) {
                         final MembershipTO membershipTO = (MembershipTO) item.getDefaultModelObject();
 
-                        item.add(new Label("roleId", new Model<Long>(membershipTO.getRoleId())));
-                        item.add(new Label("roleName", new Model<String>(membershipTO.getRoleName())));
+                        item.add(new Label("groupId", new Model<Long>(membershipTO.getGroupId())));
+                        item.add(new Label("groupName", new Model<String>(membershipTO.getGroupName())));
 
                         AjaxLink editLink = new ClearIndicatingAjaxLink("editLink", pageRef) {
 
@@ -195,15 +194,15 @@ public class MembershipsPanel extends Panel {
                                 ((UserModalPage) getPage()).getUserTO().getMemberships().remove(membershipTO);
                                 target.add(membershipsContainer);
 
-                                RoleTO roleTO = RoleUtils.findRole(roleTreeBuilder, membershipTO.getRoleId());
-                                Set<String> resourcesToRemove = roleTO == null
-                                        ? Collections.<String>emptySet() : roleTO.getResources();
+                                GroupTO groupTO = groupTreeBuilder.findGroup(membershipTO.getGroupId());
+                                Set<String> resourcesToRemove = groupTO == null
+                                        ? Collections.<String>emptySet() : groupTO.getResources();
                                 if (!resourcesToRemove.isEmpty()) {
-                                    Set<String> resourcesAssignedViaMembership = new HashSet<String>();
+                                    Set<String> resourcesAssignedViaMembership = new HashSet<>();
                                     for (MembershipTO membTO : userTO.getMemberships()) {
-                                        roleTO = RoleUtils.findRole(roleTreeBuilder, membTO.getRoleId());
-                                        if (roleTO != null) {
-                                            resourcesAssignedViaMembership.addAll(roleTO.getResources());
+                                        groupTO = groupTreeBuilder.findGroup(membTO.getGroupId());
+                                        if (groupTO != null) {
+                                            resourcesAssignedViaMembership.addAll(groupTO.getResources());
                                         }
                                     }
                                     resourcesToRemove.removeAll(resourcesAssignedViaMembership);
@@ -236,11 +235,11 @@ public class MembershipsPanel extends Panel {
                         Set<Long> diff = new HashSet<Long>(updatedUserTO.getMembershipMap().keySet());
                         diff.removeAll(userTO.getMembershipMap().keySet());
 
-                        Set<String> resourcesToAdd = new HashSet<String>();
+                        Set<String> resourcesToAdd = new HashSet<>();
                         for (Long diffMembId : diff) {
-                            long roleId = updatedUserTO.getMembershipMap().get(diffMembId).getRoleId();
-                            RoleTO roleTO = RoleUtils.findRole(roleTreeBuilder, roleId);
-                            resourcesToAdd.addAll(roleTO.getResources());
+                            long groupId = updatedUserTO.getMembershipMap().get(diffMembId).getGroupId();
+                            GroupTO groupTO = groupTreeBuilder.findGroup(groupId);
+                            resourcesToAdd.addAll(groupTO.getResources());
                             StatusUtils.update(
                                     userTO, statusPanel, target, resourcesToAdd, Collections.<String>emptySet());
                         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/PlainAttrsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/PlainAttrsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/PlainAttrsPanel.java
index 8e42318..1cf25ef 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/PlainAttrsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/PlainAttrsPanel.java
@@ -34,9 +34,9 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.commons.AttrLayoutType;
 import org.apache.syncope.client.console.commons.JexlHelpUtil;
 import org.apache.syncope.client.console.commons.Mode;
-import org.apache.syncope.client.console.panels.AttrTemplatesPanel.RoleAttrTemplatesChange;
+import org.apache.syncope.client.console.panels.AttrTemplatesPanel.GroupAttrTemplatesChange;
 import org.apache.syncope.client.console.rest.ConfigurationRestClient;
-import org.apache.syncope.client.console.rest.RoleRestClient;
+import org.apache.syncope.client.console.rest.GroupRestClient;
 import org.apache.syncope.client.console.rest.SchemaRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
@@ -54,7 +54,7 @@ import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConfTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
-import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.common.lib.types.AttributableType;
@@ -81,7 +81,7 @@ public class PlainAttrsPanel extends Panel {
     private ConfigurationRestClient confRestClient;
 
     @SpringBean
-    private RoleRestClient roleRestClient;
+    private GroupRestClient groupRestClient;
 
     private final AbstractAttributableTO entityTO;
 
@@ -147,18 +147,18 @@ public class PlainAttrsPanel extends Panel {
         AttrTO attrLayout = null;
         List<PlainSchemaTO> schemaTOs;
 
-        if (entityTO instanceof RoleTO) {
-            final RoleTO roleTO = (RoleTO) entityTO;
+        if (entityTO instanceof GroupTO) {
+            final GroupTO groupTO = (GroupTO) entityTO;
 
-            attrLayout = confRestClient.readAttrLayout(AttrLayoutType.valueOf(mode, AttributableType.ROLE));
-            schemaTOs = schemaRestClient.getSchemas(AttributableType.ROLE);
+            attrLayout = confRestClient.readAttrLayout(AttrLayoutType.valueOf(mode, AttributableType.GROUP));
+            schemaTOs = schemaRestClient.getSchemas(AttributableType.GROUP);
             Set<String> allowed;
             if (attrTemplates == null) {
-                allowed = new HashSet<>(roleTO.getRPlainAttrTemplates());
+                allowed = new HashSet<>(groupTO.getGPlainAttrTemplates());
             } else {
-                allowed = new HashSet<>(attrTemplates.getSelected(AttrTemplatesPanel.Type.rPlainAttrTemplates));
-                if (roleTO.isInheritTemplates() && roleTO.getParent() != 0) {
-                    allowed.addAll(roleRestClient.read(roleTO.getParent()).getRPlainAttrTemplates());
+                allowed = new HashSet<>(attrTemplates.getSelected(AttrTemplatesPanel.Type.gPlainAttrTemplates));
+                if (groupTO.isInheritTemplates() && groupTO.getParent() != 0) {
+                    allowed.addAll(groupRestClient.read(groupTO.getParent()).getGPlainAttrTemplates());
                 }
             }
             schemaRestClient.filter(schemaTOs, allowed, true);
@@ -169,7 +169,7 @@ public class PlainAttrsPanel extends Panel {
             attrLayout = confRestClient.readAttrLayout(AttrLayoutType.valueOf(mode, AttributableType.MEMBERSHIP));
             schemaTOs = schemaRestClient.getSchemas(AttributableType.MEMBERSHIP);
             Set<String> allowed = new HashSet<>(
-                    roleRestClient.read(((MembershipTO) entityTO).getRoleId()).getMPlainAttrTemplates());
+                    groupRestClient.read(((MembershipTO) entityTO).getGroupId()).getMPlainAttrTemplates());
             schemaRestClient.filter(schemaTOs, allowed, true);
         } else {
             schemas = new TreeMap<>();
@@ -383,9 +383,9 @@ public class PlainAttrsPanel extends Panel {
 
     @Override
     public void onEvent(final IEvent<?> event) {
-        if ((event.getPayload() instanceof RoleAttrTemplatesChange)) {
-            final RoleAttrTemplatesChange update = (RoleAttrTemplatesChange) event.getPayload();
-            if (attrTemplates != null && update.getType() == AttrTemplatesPanel.Type.rPlainAttrTemplates) {
+        if ((event.getPayload() instanceof GroupAttrTemplatesChange)) {
+            final GroupAttrTemplatesChange update = (GroupAttrTemplatesChange) event.getPayload();
+            if (attrTemplates != null && update.getType() == AttrTemplatesPanel.Type.gPlainAttrTemplates) {
                 setSchemas();
                 setAttrs();
                 update.getTarget().add(this);

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/PolicyBeanPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/PolicyBeanPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/PolicyBeanPanel.java
index 67d6684..a55be9f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/PolicyBeanPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/PolicyBeanPanel.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.panels;
 import java.beans.PropertyDescriptor;
 import java.io.Serializable;
 import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -58,6 +59,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.util.ClassUtils;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.util.ReflectionUtils.FieldCallback;
+import org.springframework.util.ReflectionUtils.FieldFilter;
 
 public class PolicyBeanPanel extends Panel {
 
@@ -84,13 +88,13 @@ public class PolicyBeanPanel extends Panel {
         }
     };
 
-    final IModel<List<String>> roleSchemas = new LoadableDetachableModel<List<String>>() {
+    final IModel<List<String>> groupSchemas = new LoadableDetachableModel<List<String>>() {
 
         private static final long serialVersionUID = 5275935387613157437L;
 
         @Override
         protected List<String> load() {
-            return schemaRestClient.getPlainSchemaNames(AttributableType.ROLE);
+            return schemaRestClient.getPlainSchemaNames(AttributableType.GROUP);
         }
     };
 
@@ -108,9 +112,10 @@ public class PolicyBeanPanel extends Panel {
         super(id);
 
         final List<FieldWrapper> items = new ArrayList<>();
+        ReflectionUtils.doWithFields(policy.getClass(), new FieldCallback() {
 
-        for (Field field : policy.getClass().getDeclaredFields()) {
-            if (!"serialVersionUID".equals(field.getName())) {
+            @Override
+            public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException {
                 FieldWrapper fieldWrapper = new FieldWrapper();
                 fieldWrapper.setName(field.getName());
                 fieldWrapper.setType(field.getType());
@@ -123,7 +128,14 @@ public class PolicyBeanPanel extends Panel {
 
                 items.add(fieldWrapper);
             }
-        }
+        },
+                new FieldFilter() {
+
+                    @Override
+                    public boolean matches(final Field field) {
+                        return !Modifier.isStatic(field.getModifiers()) && !"serialVersionUID".equals(field.getName());
+                    }
+                });
 
         final ListView<FieldWrapper> policies = new AltListView<FieldWrapper>("policies", items) {
 
@@ -185,7 +197,7 @@ public class PolicyBeanPanel extends Panel {
                         if (field.getSchemaList() != null) {
                             final List<String> values = new ArrayList<>();
                             if (field.getName().charAt(0) == 'r') {
-                                values.addAll(roleSchemas.getObject());
+                                values.addAll(groupSchemas.getObject());
 
                                 if (field.getSchemaList().extended()) {
                                     values.add("name");

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
index ecd7e0c..3940421 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
@@ -120,7 +120,7 @@ public class ResourceMappingPanel extends Panel {
     private final ResourceTO resourceTO;
 
     /**
-     * User / role.
+     * User / group.
      */
     private final AttributableType attrType;
 
@@ -145,11 +145,11 @@ public class ResourceMappingPanel extends Panel {
             }
             result = this.resourceTO.getUmapping();
         }
-        if (AttributableType.ROLE == this.attrType) {
-            if (this.resourceTO.getRmapping() == null) {
-                this.resourceTO.setRmapping(new MappingTO());
+        if (AttributableType.GROUP == this.attrType) {
+            if (this.resourceTO.getGmapping() == null) {
+                this.resourceTO.setGmapping(new MappingTO());
             }
-            result = this.resourceTO.getRmapping();
+            result = this.resourceTO.getGmapping();
         }
 
         return result;
@@ -160,7 +160,7 @@ public class ResourceMappingPanel extends Panel {
      *
      * @param id panel id
      * @param resourceTO external resource
-     * @param attrType USER / ROLE
+     * @param attrType USER / GROUP
      */
     public ResourceMappingPanel(final String id, final ResourceTO resourceTO, final AttributableType attrType) {
         super(id);
@@ -324,8 +324,8 @@ public class ResourceMappingPanel extends Panel {
                         new AjaxDropDownChoicePanel<AttributableType>("entities",
                                 new ResourceModel("entities", "entities").getObject(), new Model<AttributableType>(
                                         entity));
-                entitiesPanel.setChoices(attrType == AttributableType.ROLE
-                        ? Collections.<AttributableType>singletonList(AttributableType.ROLE)
+                entitiesPanel.setChoices(attrType == AttributableType.GROUP
+                        ? Collections.<AttributableType>singletonList(AttributableType.GROUP)
                         : Arrays.asList(AttributableType.values()));
                 entitiesPanel.setStyleSheet(DEF_FIELD_STYLE);
                 entitiesPanel.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
@@ -512,7 +512,7 @@ public class ResourceMappingPanel extends Panel {
 
         boolean enabled = objectClasses.isEmpty()
                 || (AttributableType.USER == attrType && objectClasses.contains(ConnIdObjectClassTO.ACCOUNT))
-                || (AttributableType.ROLE == attrType && objectClasses.contains(ConnIdObjectClassTO.GROUP));
+                || (AttributableType.GROUP == attrType && objectClasses.contains(ConnIdObjectClassTO.GROUP));
         this.mappingContainer.setEnabled(enabled);
         this.mappingContainer.setVisible(enabled);
         this.accountLinkContainer.setEnabled(enabled);
@@ -563,19 +563,19 @@ public class ResourceMappingPanel extends Panel {
             switch (type) {
                 // user attribute names
                 case UserPlainSchema:
-                case RolePlainSchema:
+                case GroupPlainSchema:
                 case MembershipPlainSchema:
                     toBeUpdated.setChoices(schemaRestClient.getPlainSchemaNames(type.getAttributableType()));
                     break;
 
                 case UserDerivedSchema:
-                case RoleDerivedSchema:
+                case GroupDerivedSchema:
                 case MembershipDerivedSchema:
                     toBeUpdated.setChoices(schemaRestClient.getDerSchemaNames(type.getAttributableType()));
                     break;
 
                 case UserVirtualSchema:
-                case RoleVirtualSchema:
+                case GroupVirtualSchema:
                 case MembershipVirtualSchema:
                     toBeUpdated.setChoices(schemaRestClient.getVirSchemaNames(type.getAttributableType()));
                     break;
@@ -583,8 +583,8 @@ public class ResourceMappingPanel extends Panel {
                 case UserId:
                 case Password:
                 case Username:
-                case RoleId:
-                case RoleName:
+                case GroupId:
+                case GroupName:
                 default:
                     toBeUpdated.setRequired(false);
                     toBeUpdated.setEnabled(false);
@@ -606,7 +606,7 @@ public class ResourceMappingPanel extends Panel {
         if (type != null && type.getAttributableType() != null) {
             switch (type) {
                 case UserVirtualSchema:
-                case RoleVirtualSchema:
+                case GroupVirtualSchema:
                 case MembershipVirtualSchema:
                 // Virtual accountId is not permitted
                 case Password:

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourcesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourcesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourcesPanel.java
index 67e2281..6dd1d06 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourcesPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourcesPanel.java
@@ -25,8 +25,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.commons.RoleTreeBuilder;
-import org.apache.syncope.client.console.commons.RoleUtils;
+import org.apache.syncope.client.console.commons.GroupTreeBuilder;
 import org.apache.syncope.client.console.commons.SelectChoiceRenderer;
 import org.apache.syncope.client.console.commons.status.StatusUtils;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
@@ -35,7 +34,7 @@ import org.apache.syncope.client.console.wicket.markup.html.form.NonI18nPalette;
 import org.apache.syncope.common.lib.to.AbstractSubjectTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
-import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
@@ -56,7 +55,7 @@ public class ResourcesPanel extends Panel {
     private ResourceRestClient resourceRestClient;
 
     @SpringBean
-    private RoleTreeBuilder roleTreeBuilder;
+    private GroupTreeBuilder groupTreeBuilder;
 
     private final AbstractSubjectTO subjectTO;
 
@@ -109,7 +108,7 @@ public class ResourcesPanel extends Panel {
             resourcesPalette = new AjaxRecordingPalettePanel<>("resourcesPalette",
                     new PropertyModel<List<String>>(subjectTO, "resources"),
                     new ListModel<>(allResources), builder.statusPanel);
-        } else if (subjectTO instanceof RoleTO) {
+        } else if (subjectTO instanceof GroupTO) {
             resourcesPalette = new AjaxPalettePanel<>("resourcesPalette",
                     new PropertyModel<List<String>>(subjectTO, "resources"), new ListModel<>(allResources));
         }
@@ -149,14 +148,14 @@ public class ResourcesPanel extends Panel {
                             if (subjectTO instanceof UserTO) {
                                 UserTO userTO = (UserTO) subjectTO;
 
-                                Set<String> resourcesToRemove = new HashSet<String>(previousResources);
+                                Set<String> resourcesToRemove = new HashSet<>(previousResources);
                                 resourcesToRemove.removeAll(userTO.getResources());
                                 if (!resourcesToRemove.isEmpty()) {
-                                    Set<String> resourcesAssignedViaMembership = new HashSet<String>();
+                                    Set<String> resourcesAssignedViaMembership = new HashSet<>();
                                     for (MembershipTO membTO : userTO.getMemberships()) {
-                                        RoleTO roleTO = RoleUtils.findRole(roleTreeBuilder, membTO.getRoleId());
-                                        if (roleTO != null) {
-                                            resourcesAssignedViaMembership.addAll(roleTO.getResources());
+                                        GroupTO groupTO = groupTreeBuilder.findGroup(membTO.getGroupId());
+                                        if (groupTO != null) {
+                                            resourcesAssignedViaMembership.addAll(groupTO.getResources());
                                         }
                                     }
                                     resourcesToRemove.removeAll(resourcesAssignedViaMembership);


Mime
View raw message