syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject [16/51] [partial] syncope git commit: [SYNCOPE-156] Preparing place for new console
Date Wed, 22 Apr 2015 13:51:43 GMT
http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
new file mode 100644
index 0000000..6139ee4
--- /dev/null
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
@@ -0,0 +1,353 @@
+/*
+ * 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.Collection;
+import java.util.List;
+import org.apache.syncope.client.console.commons.AttributableDataProvider;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.PreferenceManager;
+import org.apache.syncope.client.console.commons.XMLRolesReader;
+import org.apache.syncope.client.console.pages.AbstractBasePage;
+import org.apache.syncope.client.console.rest.AbstractSubjectRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.event.IEventSource;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+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.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractSearchResultPanel extends Panel implements IEventSource {
+
+    private static final long serialVersionUID = -9170191461250434024L;
+
+    /**
+     * Logger.
+     */
+    protected static final Logger LOG = LoggerFactory.getLogger(AbstractSearchResultPanel.class);
+
+    /**
+     * Edit modal window height.
+     */
+    private final static int EDIT_MODAL_WIN_HEIGHT = 550;
+
+    /**
+     * Edit modal window width.
+     */
+    private final static int EDIT_MODAL_WIN_WIDTH = 800;
+
+    /**
+     * Schemas to be shown modal window height.
+     */
+    private final static int DISPLAYATTRS_MODAL_WIN_HEIGHT = 550;
+
+    /**
+     * Schemas to be shown modal window width.
+     */
+    private final static int DISPLAYATTRS_MODAL_WIN_WIDTH = 550;
+
+    /**
+     * Schemas to be shown modal window height.
+     */
+    private final static int STATUS_MODAL_WIN_HEIGHT = 500;
+
+    /**
+     * Schemas to be shown modal window width.
+     */
+    private final static int STATUS_MODAL_WIN_WIDTH = 700;
+
+    /**
+     * Application preferences.
+     */
+    @SpringBean
+    protected PreferenceManager prefMan;
+
+    /**
+     * Role reader for authorizations management.
+     */
+    @SpringBean
+    protected XMLRolesReader xmlRolesReader;
+
+    protected final AbstractSubjectRestClient restClient;
+
+    /**
+     * Number of rows per page.
+     */
+    private final int rows;
+
+    /**
+     * Container used to refresh table.
+     */
+    protected final WebMarkupContainer container;
+
+    /**
+     * Feedback panel specified by the caller.
+     */
+    protected final NotificationPanel feedbackPanel;
+
+    /**
+     * Specify if results are about a filtered search or not. Using this attribute it is possible to use this panel to
+     * show results about user list and user search.
+     */
+    private final boolean filtered;
+
+    /**
+     * Filter used in case of filtered search.
+     */
+    private String fiql;
+
+    /**
+     * Result table.
+     */
+    private AjaxDataTablePanel<AbstractAttributableTO, String> resultTable;
+
+    /**
+     * Data provider used to search for users.
+     */
+    private AttributableDataProvider dataProvider;
+
+    /**
+     * Modal window to be used for user profile editing. Global visibility is required ...
+     */
+    protected final ModalWindow editmodal = new ModalWindow("editModal");
+
+    /**
+     * Modal window to be used for attributes choosing to display in tables.
+     */
+    protected final ModalWindow displaymodal = new ModalWindow("displayModal");
+
+    /**
+     * Modal window to be used for user status management.
+     */
+    protected final ModalWindow statusmodal = new ModalWindow("statusModal");
+
+    /**
+     * Owner page.
+     */
+    protected final AbstractBasePage page;
+
+    protected <T extends AbstractAttributableTO> AbstractSearchResultPanel(final String id, final boolean filtered,
+            final String fiql, final PageReference pageRef, final AbstractSubjectRestClient restClient) {
+
+        super(id);
+
+        setOutputMarkupId(true);
+
+        this.page = (AbstractBasePage) pageRef.getPage();
+
+        this.filtered = filtered;
+        this.fiql = fiql;
+        this.feedbackPanel = page.getFeedbackPanel();
+
+        this.restClient = restClient;
+
+        editmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        editmodal.setInitialHeight(EDIT_MODAL_WIN_HEIGHT);
+        editmodal.setInitialWidth(EDIT_MODAL_WIN_WIDTH);
+        editmodal.setCookieName("edit-modal");
+        add(editmodal);
+
+        displaymodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        displaymodal.setInitialHeight(DISPLAYATTRS_MODAL_WIN_HEIGHT);
+        displaymodal.setInitialWidth(DISPLAYATTRS_MODAL_WIN_WIDTH);
+        displaymodal.setCookieName("display-modal");
+        add(displaymodal);
+
+        statusmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        statusmodal.setInitialHeight(STATUS_MODAL_WIN_HEIGHT);
+        statusmodal.setInitialWidth(STATUS_MODAL_WIN_WIDTH);
+        statusmodal.setCookieName("status-modal");
+        add(statusmodal);
+
+        // Container for user search result
+        container = new WebMarkupContainer("container");
+        container.setOutputMarkupId(true);
+        add(container);
+
+        rows = prefMan.getPaginatorRows(getRequest(), Constants.PREF_USERS_PAGINATOR_ROWS);
+    }
+
+    protected void initResultTable() {
+        // ---------------------------
+        // Result table initialization
+        // ---------------------------
+        updateResultTable(false);
+        // ---------------------------
+
+        // ---------------------------
+        // Rows-per-page selector
+        // ---------------------------
+        final Form<?> paginatorForm = new Form<>("paginator");
+        container.add(paginatorForm);
+
+        final DropDownChoice<Integer> rowsChooser = new DropDownChoice<>(
+                "rowsChooser", new PropertyModel<Integer>(this, "rows"), prefMan.getPaginatorChoices());
+
+        rowsChooser.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                prefMan.set(getRequest(), getResponse(), Constants.PREF_USERS_PAGINATOR_ROWS, String.valueOf(rows));
+
+                final EventDataWrapper data = new EventDataWrapper();
+                data.setTarget(target);
+                data.setRows(rows);
+
+                send(getParent(), Broadcast.BREADTH, data);
+            }
+        });
+        paginatorForm.add(rowsChooser);
+        // ---------------------------
+
+        setWindowClosedReloadCallback(statusmodal);
+        setWindowClosedReloadCallback(editmodal);
+        setWindowClosedReloadCallback(displaymodal);
+    }
+
+    public void search(final String fiql, final AjaxRequestTarget target) {
+        this.fiql = fiql;
+        dataProvider.setFIQL(fiql);
+        target.add(container);
+    }
+
+    private void updateResultTable(final boolean create) {
+        updateResultTable(create, rows);
+    }
+
+    private void updateResultTable(final boolean create, final int rows) {
+        dataProvider = new AttributableDataProvider(restClient, rows, filtered);
+        dataProvider.setFIQL(fiql);
+
+        final int currentPage = resultTable != null
+                ? (create
+                        ? (int) resultTable.getPageCount() - 1
+                        : (int) resultTable.getCurrentPage())
+                : 0;
+
+        resultTable = new AjaxDataTablePanel<>(
+                "resultTable",
+                getColumns(),
+                dataProvider,
+                rows,
+                getBulkActions(),
+                restClient,
+                "key",
+                getPageId(),
+                page.getPageReference());
+
+        resultTable.setCurrentPage(currentPage);
+
+        resultTable.setOutputMarkupId(true);
+
+        container.addOrReplace(resultTable);
+    }
+
+    protected abstract List<IColumn<AbstractAttributableTO, String>> getColumns();
+
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        if (event.getPayload() instanceof EventDataWrapper) {
+            final EventDataWrapper data = (EventDataWrapper) event.getPayload();
+
+            if (data.getRows() < 1) {
+                updateResultTable(data.isCreate());
+            } else {
+                updateResultTable(data.isCreate(), data.getRows());
+            }
+
+            data.getTarget().add(container);
+        }
+    }
+
+    private void setWindowClosedReloadCallback(final ModalWindow window) {
+        window.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+            private static final long serialVersionUID = 8804221891699487139L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                final EventDataWrapper data = new EventDataWrapper();
+                data.setTarget(target);
+                data.setRows(rows);
+
+                send(getParent(), Broadcast.BREADTH, data);
+
+                if (page.isModalResult()) {
+                    // reset modal result
+                    page.setModalResult(false);
+                    // set operation succeeded
+                    getSession().info(getString(Constants.OPERATION_SUCCEEDED));
+                    // refresh feedback panel
+                    feedbackPanel.refresh(target);
+                }
+            }
+        });
+    }
+
+    public static class EventDataWrapper {
+
+        private AjaxRequestTarget target;
+
+        private boolean create;
+
+        private int rows;
+
+        public AjaxRequestTarget getTarget() {
+            return target;
+        }
+
+        public void setTarget(final AjaxRequestTarget target) {
+            this.target = target;
+        }
+
+        public boolean isCreate() {
+            return create;
+        }
+
+        public void setCreate(boolean create) {
+            this.create = create;
+        }
+
+        public int getRows() {
+            return rows;
+        }
+
+        public void setRows(int rows) {
+            this.rows = rows;
+        }
+    }
+
+    protected abstract <T extends AbstractAttributableTO> Collection<ActionLink.ActionType> getBulkActions();
+
+    protected abstract String getPageId();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AbstractTasks.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AbstractTasks.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AbstractTasks.java
new file mode 100644
index 0000000..381f878
--- /dev/null
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AbstractTasks.java
@@ -0,0 +1,55 @@
+/*
+ * 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.PreferenceManager;
+import org.apache.syncope.client.console.commons.XMLRolesReader;
+import org.apache.syncope.client.console.rest.TaskRestClient;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public abstract class AbstractTasks extends Panel {
+
+    private static final long serialVersionUID = -1190836516156843561L;
+
+    protected static final String VIEW_TASK_WIN_COOKIE_NAME = "view-task-win";
+
+    protected static final int WIN_HEIGHT = 500;
+
+    protected static final int WIN_WIDTH = 700;
+
+    protected static final String TASKS = "Tasks";
+
+    protected PageReference pageRef;
+
+    @SpringBean
+    protected TaskRestClient restClient;
+
+    @SpringBean
+    protected PreferenceManager prefMan;
+
+    @SpringBean
+    protected XMLRolesReader xmlRolesReader;
+
+    public AbstractTasks(final String id, final PageReference pageRef) {
+        super(id);
+        this.pageRef = pageRef;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AccountInformationPanel.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AccountInformationPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AccountInformationPanel.java
new file mode 100644
index 0000000..3bc7dd8
--- /dev/null
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AccountInformationPanel.java
@@ -0,0 +1,73 @@
+/*
+ * 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.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeSession;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.model.Model;
+
+public class AccountInformationPanel extends AnnotatedBeanPanel {
+
+    private static final long serialVersionUID = 4228064224811390808L;
+
+    public <T extends AbstractAttributableTO> AccountInformationPanel(final String id, final UserTO userTO) {
+        super(id, userTO);
+
+        // ------------------------
+        // Change password date
+        // ------------------------
+        add(new Label("changePwdDate", new Model<String>(userTO.getChangePwdDate() == null
+                ? StringUtils.EMPTY
+                : SyncopeSession.get().getDateFormat().format(userTO.getChangePwdDate()))));
+        // ------------------------
+
+        // ------------------------
+        // Last login date
+        // ------------------------
+        add(new Label("lastLoginDate", new Model<String>(userTO.getLastLoginDate() == null
+                ? StringUtils.EMPTY
+                : SyncopeSession.get().getDateFormat().format(userTO.getLastLoginDate()))));
+        // ------------------------
+
+        // ------------------------
+        // Failed logins
+        // ------------------------
+        add(new Label("failedLogins", new Model<Integer>(userTO.getFailedLogins())));
+        // ------------------------
+
+        // ------------------------
+        // Token
+        // ------------------------
+        add(new Label("token", new Model<String>(userTO.getToken() == null
+                ? StringUtils.EMPTY
+                : userTO.getToken())));
+        // ------------------------
+
+        // ------------------------
+        // Token expire time
+        // ------------------------
+        add(new Label("tokenExpireTime", new Model<String>(userTO.getTokenExpireTime() == null
+                ? StringUtils.EMPTY
+                : SyncopeSession.get().getDateFormat().format(userTO.getTokenExpireTime()))));
+        // ------------------------
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
new file mode 100644
index 0000000..bfade98
--- /dev/null
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
@@ -0,0 +1,149 @@
+/*
+ * 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.Collection;
+import java.util.List;
+import org.apache.syncope.client.console.commons.ActionTableCheckGroup;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CheckGroupColumn;
+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.wicket.AttributeModifier;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+
+public class ActionDataTablePanel<T, S> extends DataTablePanel<T, S> {
+
+    private static final long serialVersionUID = -8826989026203543957L;
+
+    private static final String CANCEL = "cancel";
+
+    private final Form<T> bulkActionForm;
+
+    private final ActionLinksPanel actionPanel;
+
+    private final PageReference pageRef;
+
+    public ActionDataTablePanel(
+            final String id,
+            final List<IColumn<T, S>> columns,
+            final ISortableDataProvider<T, S> dataProvider,
+            final int rowsPerPage,
+            final PageReference pageRef) {
+
+        super(id);
+
+        this.pageRef = pageRef;
+
+        bulkActionForm = new Form<T>("groupForm");
+        add(bulkActionForm);
+
+        group = new ActionTableCheckGroup<T>("checkgroup", model) {
+
+            private static final long serialVersionUID = -8667764190925075389L;
+
+            @Override
+            public boolean isCheckable(final T element) {
+                return isElementEnabled(element);
+            }
+        };
+        group.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+            private static final long serialVersionUID = -151291731388673682L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                // triggers AJAX form submit
+            }
+        });
+        bulkActionForm.add(group);
+
+        columns.add(0, new CheckGroupColumn<T, S>(group));
+        dataTable = new AjaxFallbackDefaultDataTable<T, S>("dataTable", columns, dataProvider, rowsPerPage);
+        group.add(dataTable);
+
+        final WebMarkupContainer actionPanelContainer = new WebMarkupContainer("actionPanelContainer");
+        bulkActionForm.add(actionPanelContainer);
+
+        actionPanel = new ActionLinksPanel("actions", new Model(), pageRef);
+        actionPanelContainer.add(actionPanel);
+
+        if (dataTable.getRowCount() == 0) {
+            actionPanelContainer.add(new AttributeModifier("style", "display: none"));
+        }
+
+        bulkActionForm.add(new ClearIndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL), pageRef) {
+
+            private static final long serialVersionUID = -2341391430136818025L;
+
+            @Override
+            protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) {
+                // ignore
+            }
+        }.setVisible(false).setEnabled(false));
+    }
+
+    public void addAction(final ActionLink action, final ActionType type, final String pageId) {
+        actionPanel.add(action, type, pageId);
+    }
+
+    public void addAction(final ActionLink action, final ActionType type, final String pageId, final String actionId) {
+        actionPanel.add(action, type, pageId, actionId);
+    }
+
+    public void addAction(final ActionLink action, final ActionType type, final String pageId, final boolean enabled) {
+        actionPanel.add(action, type, pageId, enabled);
+    }
+
+    public void addCancelButton(final ModalWindow window) {
+
+        final AjaxButton cancel = new ClearIndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL), pageRef) {
+
+            private static final long serialVersionUID = -2341391430136818025L;
+
+            @Override
+            protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) {
+                window.close(target);
+            }
+        }.feedbackPanelAutomaticReload(false);
+
+        cancel.setDefaultFormProcessing(false);
+        bulkActionForm.addOrReplace(cancel);
+    }
+
+    public Collection<T> getModelObject() {
+        return group.getModelObject();
+    }
+
+    public boolean isElementEnabled(final T element) {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
new file mode 100644
index 0000000..563bd17
--- /dev/null
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
@@ -0,0 +1,142 @@
+/*
+ * 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.Collection;
+import java.util.List;
+import org.apache.syncope.client.console.rest.BaseRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.panels.AbstractSearchResultPanel.EventDataWrapper;
+import org.apache.syncope.client.console.pages.AbstractBasePage;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CheckGroupColumn;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
+import org.apache.syncope.client.console.pages.BulkActionModalPage;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Fragment;
+
+public class AjaxDataTablePanel<T, S> extends DataTablePanel<T, S> {
+
+    private static final long serialVersionUID = -7264400471578272966L;
+
+    public AjaxDataTablePanel(
+            final String id,
+            final List<IColumn<T, S>> columns,
+            final ISortableDataProvider<T, S> dataProvider,
+            final int rowsPerPage,
+            final Collection<ActionLink.ActionType> actions,
+            final BaseRestClient bulkActionExecutor,
+            final String itemIdField,
+            final String pageId,
+            final PageReference pageRef) {
+
+        super(id);
+
+        final ModalWindow bulkModalWin = new ModalWindow("bulkModal");
+        bulkModalWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        bulkModalWin.setInitialHeight(600);
+        bulkModalWin.setInitialWidth(900);
+        bulkModalWin.setCookieName("bulk-modal");
+        add(bulkModalWin);
+
+        bulkModalWin.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+            private static final long serialVersionUID = 8804221891699487149L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                final EventDataWrapper data = new EventDataWrapper();
+                data.setTarget(target);
+                data.setRows(rowsPerPage);
+
+                send(pageRef.getPage(), Broadcast.BREADTH, data);
+
+                final AbstractBasePage page = (AbstractBasePage) pageRef.getPage();
+
+                if (page.isModalResult()) {
+                    // reset modal result
+                    page.setModalResult(false);
+                    // set operation succeeded
+                    getSession().info(getString(Constants.OPERATION_SUCCEEDED));
+                    // refresh feedback panel
+                    target.add(page.getFeedbackPanel());
+                }
+            }
+        });
+
+        Fragment fragment = new Fragment("tablePanel", "bulkAvailable", this);
+        add(fragment);
+
+        Form<T> bulkActionForm = new Form<>("groupForm");
+        fragment.add(bulkActionForm);
+
+        group = new CheckGroup<>("checkgroup", model);
+        group.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+            private static final long serialVersionUID = -151291731388673682L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                // triggers AJAX form submit
+            }
+        });
+        bulkActionForm.add(group);
+
+        columns.add(0, new CheckGroupColumn<T, S>(group));
+        dataTable = new AjaxFallbackDefaultDataTable<>("dataTable", columns, dataProvider, rowsPerPage);
+        group.add(dataTable);
+
+        fragment.add(new ClearIndicatingAjaxButton("bulkActionLink", bulkActionForm, pageRef) {
+
+            private static final long serialVersionUID = 382302811235019988L;
+
+            @Override
+            protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) {
+                bulkModalWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                    private static final long serialVersionUID = -7834632442532690941L;
+
+                    @Override
+                    public Page createPage() {
+                        return new BulkActionModalPage<>(
+                                bulkModalWin,
+                                group.getModelObject(),
+                                columns,
+                                actions,
+                                bulkActionExecutor,
+                                itemIdField,
+                                pageId);
+                    }
+                });
+
+                bulkModalWin.show(target);
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
new file mode 100644
index 0000000..714cb5f
--- /dev/null
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
@@ -0,0 +1,66 @@
+/*
+ * 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.SyncopeSession;
+import org.apache.syncope.common.lib.to.AbstractAnnotatedBean;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+
+public class AnnotatedBeanPanel extends Panel {
+
+    private static final long serialVersionUID = 4228064224811390809L;
+
+    public <T extends AbstractAttributableTO> AnnotatedBeanPanel(
+            final String id, final AbstractAnnotatedBean sysInfoTO) {
+
+        super(id);
+
+        // ------------------------
+        // Creation date
+        // ------------------------
+        add(new Label("creationDate", new Model<String>(sysInfoTO.getCreationDate() != null
+                ? SyncopeSession.get().getDateFormat().format(sysInfoTO.getCreationDate()) : "")));
+        // ------------------------
+
+        // ------------------------
+        // Last change date
+        // ------------------------
+        add(new Label("lastChangeDate", new Model<String>(sysInfoTO.getLastChangeDate() != null
+                ? SyncopeSession.get().getDateFormat().format(sysInfoTO.getCreationDate()) : "")));
+        // ------------------------
+
+        // ------------------------
+        // Creator
+        // ------------------------
+        add(new Label("creator", new Model<String>(sysInfoTO.getCreator() != null
+                ? sysInfoTO.getCreator() : "")));
+        // ------------------------
+
+        // ------------------------
+        // Last modifier
+        // ------------------------
+        add(new Label("lastModifier", new Model<String>(sysInfoTO.getLastModifier() != null
+                ? sysInfoTO.getLastModifier() : "")));
+        // ------------------------
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AttrTemplatesPanel.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AttrTemplatesPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AttrTemplatesPanel.java
new file mode 100644
index 0000000..98ada28
--- /dev/null
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/AttrTemplatesPanel.java
@@ -0,0 +1,167 @@
+/*
+ * 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.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.SelectChoiceRenderer;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.NonI18nPalette;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.extensions.markup.html.form.palette.component.Recorder;
+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 AttrTemplatesPanel extends Panel {
+
+    public enum Type {
+
+        gPlainAttrTemplates,
+        gDerAttrTemplates,
+        gVirAttrTemplates,
+        mPlainAttrTemplates,
+        mDerAttrTemplates,
+        mVirAttrTemplates;
+
+    }
+
+    private static final long serialVersionUID = 1016028222120619000L;
+
+    @SpringBean
+    private SchemaRestClient schemaRestClient;
+
+    private final GroupTO groupTO;
+
+    private final NonI18nPalette<String> rPlainAttrTemplates;
+
+    private final NonI18nPalette<String> rDerAttrTemplates;
+
+    private final NonI18nPalette<String> rVirAttrTemplates;
+
+    public AttrTemplatesPanel(final String id, final GroupTO groupTO) {
+        super(id);
+        this.groupTO = groupTO;
+
+        rPlainAttrTemplates = buildPalette(Type.gPlainAttrTemplates,
+                schemaRestClient.getSchemaNames(AttributableType.GROUP, SchemaType.PLAIN));
+        this.add(rPlainAttrTemplates);
+        rDerAttrTemplates = buildPalette(Type.gDerAttrTemplates,
+                schemaRestClient.getSchemaNames(AttributableType.GROUP, SchemaType.DERIVED));
+        this.add(rDerAttrTemplates);
+        rVirAttrTemplates = buildPalette(Type.gVirAttrTemplates,
+                schemaRestClient.getSchemaNames(AttributableType.GROUP, SchemaType.VIRTUAL));
+        this.add(rVirAttrTemplates);
+
+        this.add(buildPalette(Type.mPlainAttrTemplates,
+                schemaRestClient.getSchemaNames(AttributableType.MEMBERSHIP, SchemaType.PLAIN)));
+        this.add(buildPalette(Type.mDerAttrTemplates,
+                schemaRestClient.getSchemaNames(AttributableType.MEMBERSHIP, SchemaType.DERIVED)));
+        this.add(buildPalette(Type.mVirAttrTemplates,
+                schemaRestClient.getSchemaNames(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL)));
+    }
+
+    private NonI18nPalette<String> buildPalette(final Type type, final List<String> allSchemas) {
+        if (allSchemas != null && !allSchemas.isEmpty()) {
+            Collections.sort(allSchemas);
+        }
+        ListModel<String> availableSchemas = new ListModel<>(allSchemas);
+
+        return new NonI18nPalette<String>(type.name(), new PropertyModel<List<String>>(groupTO, type.name()),
+                availableSchemas, new SelectChoiceRenderer<String>(), 8, false, true) {
+
+                    private static final long serialVersionUID = 2295567122085510330L;
+
+                    @Override
+                    protected Recorder<String> newRecorderComponent() {
+                        final Recorder<String> recorder = super.newRecorderComponent();
+
+                        switch (type) {
+                            case gPlainAttrTemplates:
+                            case gDerAttrTemplates:
+                            case gVirAttrTemplates:
+                                recorder.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, target));
+                                    }
+                                });
+                                break;
+
+                            default:
+                        }
+
+                        return recorder;
+                    }
+                };
+    }
+
+    public Collection<String> getSelected(final Type type) {
+        Collection<String> selected;
+        switch (type) {
+            case gPlainAttrTemplates:
+                selected = this.rPlainAttrTemplates.getModelCollection();
+                break;
+
+            case gDerAttrTemplates:
+                selected = this.rDerAttrTemplates.getModelCollection();
+                break;
+
+            case gVirAttrTemplates:
+                selected = this.rVirAttrTemplates.getModelCollection();
+                break;
+
+            default:
+                selected = Collections.emptyList();
+        }
+
+        return selected;
+    }
+
+    public static class GroupAttrTemplatesChange {
+
+        private final Type type;
+
+        private final AjaxRequestTarget target;
+
+        public GroupAttrTemplatesChange(final Type type, final AjaxRequestTarget target) {
+            this.type = type;
+            this.target = target;
+        }
+
+        public Type getType() {
+            return type;
+        }
+
+        public AjaxRequestTarget getTarget() {
+            return target;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
new file mode 100644
index 0000000..a5f6588
--- /dev/null
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
@@ -0,0 +1,113 @@
+/*
+ * 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.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import org.apache.wicket.Component;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.DataGridView;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class DataTablePanel<T, S> extends Panel {
+
+    private static final long serialVersionUID = -7264400471578272966L;
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(DataTablePanel.class);
+
+    protected CheckGroup<T> group;
+
+    protected AjaxFallbackDefaultDataTable<T, S> dataTable;
+
+    protected IModel<Collection<T>> model;
+
+    public DataTablePanel(final String id) {
+        super(id);
+
+        model = new IModel<Collection<T>>() {
+
+            private static final long serialVersionUID = 4886729136344643465L;
+
+            private Collection<T> values = new HashSet<T>();
+
+            @Override
+            public Collection<T> getObject() {
+                // Someone or something call this method to change the model: this is not the right behavior.
+                // Return a copy of the model object in order to avoid SYNCOPE-465
+                return new HashSet<T>(values);
+            }
+
+            @Override
+            public void setObject(final Collection<T> selected) {
+                final Collection<T> all = getGroupModelObjects();
+                values.removeAll(all);
+                values.addAll(selected);
+            }
+
+            @Override
+            public void detach() {
+            }
+        };
+    }
+
+    public final void setCurrentPage(final long page) {
+        dataTable.setCurrentPage(page);
+    }
+
+    public final long getRowCount() {
+        return dataTable.getRowCount();
+    }
+
+    public final long getCurrentPage() {
+        return dataTable.getCurrentPage();
+    }
+
+    public final long getPageCount() {
+        return dataTable.getPageCount();
+    }
+
+    public void setItemsPerPage(final int resourcePaginatorRows) {
+        dataTable.setItemsPerPage(resourcePaginatorRows);
+    }
+
+    protected Collection<T> getGroupModelObjects() {
+        final Set<T> res = new HashSet<T>();
+
+        final Component rows = group.get("dataTable:body:rows");
+        if (rows instanceof DataGridView) {
+            @SuppressWarnings("unchecked")
+            final Iterator<Item<T>> iter = ((DataGridView<T>) rows).getItems();
+
+            while (iter.hasNext()) {
+                res.add(iter.next().getModelObject());
+            }
+        }
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/DerAttrsPanel.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/DerAttrsPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/DerAttrsPanel.java
new file mode 100644
index 0000000..8be459a
--- /dev/null
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/DerAttrsPanel.java
@@ -0,0 +1,206 @@
+/*
+ * 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.List;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.AttrTemplatesPanel.GroupAttrTemplatesChange;
+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.AjaxDecoratedCheckbox;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+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.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxCallListener;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.ajax.attributes.IAjaxCallListener;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+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.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public class DerAttrsPanel extends Panel {
+
+    private static final long serialVersionUID = -5387344116983102292L;
+
+    @SpringBean
+    private SchemaRestClient schemaRestClient;
+
+    @SpringBean
+    private GroupRestClient groupRestClient;
+
+    private final AttrTemplatesPanel attrTemplates;
+
+    public <T extends AbstractAttributableTO> DerAttrsPanel(final String id, final T entityTO) {
+        this(id, entityTO, null);
+    }
+
+    public <T extends AbstractAttributableTO> DerAttrsPanel(final String id, final T entityTO,
+            final AttrTemplatesPanel attrTemplates) {
+
+        super(id);
+        this.attrTemplates = attrTemplates;
+        setOutputMarkupId(true);
+
+        final IModel<List<String>> derSchemas = new LoadableDetachableModel<List<String>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected List<String> load() {
+                List<String> derSchemaNames;
+
+                if (entityTO instanceof GroupTO) {
+                    final GroupTO groupTO = (GroupTO) entityTO;
+
+                    if (attrTemplates == null) {
+                        derSchemaNames = groupTO.getGDerAttrTemplates();
+                    } else {
+                        derSchemaNames = new ArrayList<>(
+                                attrTemplates.getSelected(AttrTemplatesPanel.Type.gDerAttrTemplates));
+                        if (groupTO.isInheritTemplates() && groupTO.getParent() != 0) {
+                            derSchemaNames.addAll(groupRestClient.read(groupTO.getParent()).getGDerAttrTemplates());
+                        }
+                    }
+                } else if (entityTO instanceof UserTO) {
+                    derSchemaNames = schemaRestClient.getDerSchemaNames(AttributableType.USER);
+                } else {
+                    derSchemaNames = groupRestClient.read(((MembershipTO) entityTO).getGroupKey()).getMDerAttrTemplates();
+                }
+
+                return derSchemaNames;
+            }
+        };
+
+        final WebMarkupContainer attributesContainer = new WebMarkupContainer("derAttrContainer");
+
+        attributesContainer.setOutputMarkupId(true);
+        add(attributesContainer);
+
+        AjaxButton addAttributeBtn = new IndicatingAjaxButton("addAttributeBtn", new ResourceModel("addAttributeBtn")) {
+
+            private static final long serialVersionUID = -4804368561204623354L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+                entityTO.getDerAttrs().add(new AttrTO());
+                target.add(attributesContainer);
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+                target.add(attributesContainer);
+            }
+        };
+        add(addAttributeBtn.setDefaultFormProcessing(false));
+
+        ListView<AttrTO> attributes = new ListView<AttrTO>("attrs",
+                new PropertyModel<List<? extends AttrTO>>(entityTO, "derAttrs")) {
+
+                    private static final long serialVersionUID = 9101744072914090143L;
+
+                    @Override
+                    protected void populateItem(final ListItem<AttrTO> item) {
+                        final AttrTO attributeTO = item.getModelObject();
+
+                        item.add(new AjaxDecoratedCheckbox("toRemove", new Model<>(Boolean.FALSE)) {
+
+                            private static final long serialVersionUID = 7170946748485726506L;
+
+                            @Override
+                            protected void onUpdate(final AjaxRequestTarget target) {
+                                entityTO.getDerAttrs().remove(attributeTO);
+                                target.add(attributesContainer);
+                            }
+
+                            @Override
+                            protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+                                super.updateAjaxAttributes(attributes);
+
+                                IAjaxCallListener ajaxCallListener = new AjaxCallListener() {
+
+                                    private static final long serialVersionUID = 7160235486520935153L;
+
+                                    @Override
+                                    public CharSequence getPrecondition(final Component component) {
+                                        return "if (!confirm('" + getString("confirmDelete") + "')) return false;";
+                                    }
+                                };
+                                attributes.getAjaxCallListeners().add(ajaxCallListener);
+                            }
+                        });
+
+                        final DropDownChoice<String> schemaChoice = new DropDownChoice<String>("schema",
+                                new PropertyModel<String>(attributeTO, "schema"), derSchemas);
+                        schemaChoice.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
+
+                            private static final long serialVersionUID = -1107858522700306810L;
+
+                            @Override
+                            protected void onUpdate(final AjaxRequestTarget target) {
+                                attributeTO.setSchema(schemaChoice.getModelObject());
+                            }
+                        });
+                        schemaChoice.setRequired(true);
+                        schemaChoice.setOutputMarkupId(true);
+                        schemaChoice.setRequired(true);
+                        item.add(schemaChoice);
+
+                        final List<String> values = attributeTO.getValues();
+                        if (values == null || values.isEmpty()) {
+                            item.add(new TextField<String>("value",
+                                            new Model<String>(null)).setVisible(false));
+                        } else {
+                            item.add(new TextField<String>("value",
+                                            new Model<String>(values.get(0))).setEnabled(false));
+                        }
+                    }
+                };
+        attributesContainer.add(attributes);
+    }
+
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        if ((event.getPayload() instanceof GroupAttrTemplatesChange)) {
+            final GroupAttrTemplatesChange update = (GroupAttrTemplatesChange) event.getPayload();
+            if (attrTemplates != null && update.getType() == AttrTemplatesPanel.Type.gDerAttrTemplates) {
+                update.getTarget().add(this);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/EventSelectionPanel.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/EventSelectionPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/EventSelectionPanel.java
new file mode 100644
index 0000000..5332cb5
--- /dev/null
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/EventSelectionPanel.java
@@ -0,0 +1,243 @@
+/*
+ * 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.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.wicket.markup.html.list.AltListView;
+import org.apache.syncope.common.lib.to.EventCategoryTO;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Check;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.form.CheckGroupSelector;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class EventSelectionPanel extends Panel {
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(EventSelectionPanel.class);
+
+    private static final long serialVersionUID = 752233163798301002L;
+
+    private final Set<String> selected = new HashSet<String>();
+
+    public EventSelectionPanel(
+            final String id, final EventCategoryTO eventCategoryTO, final IModel<List<String>> model) {
+        super(id);
+        setOutputMarkupId(true);
+
+        final List<String> events = getEvents(eventCategoryTO);
+
+        // needed to avoid model reset: model have to be managed into SelectedEventsPanel
+        selected.addAll(model.getObject());
+
+        final CheckGroup<String> successGroup = new CheckGroup<String>(
+                "successGroup",
+                selected);
+
+        successGroup.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+            private static final long serialVersionUID = -151291731388673682L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+
+                final Set<String> toBeRemoved = new HashSet<>();
+                final Set<String> toBeAdded = new HashSet<>();
+
+                for (String event : getEvents(eventCategoryTO)) {
+                    final String eventString = AuditLoggerName.buildEvent(
+                            eventCategoryTO.getType(),
+                            eventCategoryTO.getCategory(),
+                            eventCategoryTO.getSubcategory(),
+                            event,
+                            AuditElements.Result.SUCCESS);
+
+                    if (successGroup.getModelObject().contains(eventString)) {
+                        toBeAdded.add(eventString);
+                    } else {
+                        toBeRemoved.add(eventString);
+                    }
+                }
+
+                send(EventSelectionPanel.this.getPage(), Broadcast.BREADTH,
+                        new SelectedEventsPanel.EventSelectionChanged(target, toBeAdded, toBeRemoved));
+            }
+        });
+
+        successGroup.setVisible(!events.isEmpty());
+        add(successGroup);
+
+        add(new Label("successLabel", new ResourceModel("Success", "Success"))).setVisible(!events.isEmpty());
+
+        final CheckGroupSelector successSelector = new CheckGroupSelector("successSelector", successGroup);
+        successSelector.setVisible(!events.isEmpty());
+        add(successSelector);
+
+        final ListView<String> categoryView = new AltListView<String>("categoryView", events) {
+
+            private static final long serialVersionUID = 4949588177564901031L;
+
+            @Override
+            protected void populateItem(final ListItem<String> item) {
+                final String subcategory = item.getModelObject();
+
+                item.add(new Label("subcategory", new ResourceModel(subcategory, subcategory)));
+            }
+        };
+        add(categoryView);
+
+        final ListView<String> successView = new AltListView<String>("successView", events) {
+
+            private static final long serialVersionUID = 4949588177564901031L;
+
+            @Override
+            protected void populateItem(final ListItem<String> item) {
+                final String event = item.getModelObject();
+
+                final Check<String> successCheck = new Check<>("successCheck",
+                        new Model<String>(AuditLoggerName.buildEvent(
+                                        eventCategoryTO.getType(),
+                                        eventCategoryTO.getCategory(),
+                                        eventCategoryTO.getSubcategory(),
+                                        event,
+                                        AuditElements.Result.SUCCESS)),
+                        successGroup);
+                item.add(successCheck);
+            }
+        };
+        successGroup.add(successView);
+
+        final CheckGroup<String> failureGroup = new CheckGroup<String>(
+                "failureGroup",
+                selected);
+
+        failureGroup.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+            private static final long serialVersionUID = -151291731388673682L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+
+                final Set<String> toBeRemoved = new HashSet<>();
+                final Set<String> toBeAdded = new HashSet<>();
+
+                for (String event : getEvents(eventCategoryTO)) {
+                    final String eventString = AuditLoggerName.buildEvent(
+                            eventCategoryTO.getType(),
+                            eventCategoryTO.getCategory(),
+                            eventCategoryTO.getSubcategory(),
+                            event,
+                            AuditElements.Result.FAILURE);
+
+                    if (failureGroup.getModelObject().contains(eventString)) {
+                        toBeAdded.add(eventString);
+                    } else {
+                        toBeRemoved.add(eventString);
+                    }
+                }
+
+                send(EventSelectionPanel.this.getPage(), Broadcast.BREADTH,
+                        new SelectedEventsPanel.EventSelectionChanged(target, toBeAdded, toBeRemoved));
+            }
+        });
+
+        failureGroup.setVisible(!events.isEmpty());
+        add(failureGroup);
+
+        add(new Label("failureLabel", new ResourceModel("Failure", "Failure"))).setVisible(!events.isEmpty());
+
+        final CheckGroupSelector failureSelector = new CheckGroupSelector("failureSelector", failureGroup);
+        failureSelector.setVisible(!events.isEmpty());
+        add(failureSelector);
+
+        final ListView<String> failureView = new AltListView<String>("failureView", events) {
+
+            private static final long serialVersionUID = 4949588177564901031L;
+
+            @Override
+            protected void populateItem(final ListItem<String> item) {
+                final String event = item.getModelObject();
+
+                final Check<String> failureCheck = new Check<>("failureCheck",
+                        new Model<String>(AuditLoggerName.buildEvent(
+                                        eventCategoryTO.getType(),
+                                        eventCategoryTO.getCategory(),
+                                        eventCategoryTO.getSubcategory(),
+                                        event,
+                                        AuditElements.Result.FAILURE)),
+                        failureGroup);
+                item.add(failureCheck);
+            }
+        };
+        failureGroup.add(failureView);
+    }
+
+    private List<String> getEvents(final EventCategoryTO eventCategoryTO) {
+        final List<String> res;
+
+        res = eventCategoryTO.getEvents();
+
+        if (res.isEmpty()) {
+            if ((AuditElements.EventCategoryType.PROPAGATION == eventCategoryTO.getType()
+                    || AuditElements.EventCategoryType.SYNCHRONIZATION == eventCategoryTO.getType()
+                    || AuditElements.EventCategoryType.PUSH == eventCategoryTO.getType())
+                    && StringUtils.isEmpty(eventCategoryTO.getCategory())) {
+                res.add(eventCategoryTO.getType().toString());
+            } else if (AuditElements.EventCategoryType.TASK == eventCategoryTO.getType()
+                    && StringUtils.isNotEmpty(eventCategoryTO.getCategory())) {
+                res.add(eventCategoryTO.getCategory());
+            }
+        } else {
+            Collections.sort(res);
+        }
+
+        return res;
+    }
+
+    /**
+     * To be extended in order to add actions on events.
+     *
+     * @param event event.
+     */
+    protected abstract void onEventAction(final IEvent<?> event);
+
+    @Override
+    public void onEvent(final IEvent<?> event) {
+        onEventAction(event);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/GroupDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/GroupDetailsPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/GroupDetailsPanel.java
new file mode 100644
index 0000000..7662e4a
--- /dev/null
+++ b/client/old_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.JexlHelpUtils;
+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 = JexlHelpUtils.getJexlHelpWebContainer("jexlHelp");
+
+        final AjaxLink<Void> questionMarkJexlHelp = JexlHelpUtils.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;
+        }
+    }
+}


Mime
View raw message