http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PropagationTaskModalPage.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PropagationTaskModalPage.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PropagationTaskModalPage.java
new file mode 100644
index 0000000..5a6779f
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PropagationTaskModalPage.java
@@ -0,0 +1,45 @@
+/*
+ * 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.pages;
+
+import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.wicket.model.PropertyModel;
+
+/**
+ * Modal window with Task form (to stop and start execution).
+ */
+public class PropagationTaskModalPage extends TaskModalPage {
+
+    private static final long serialVersionUID = 523379887023786151L;
+
+    public PropagationTaskModalPage(final AbstractTaskTO taskTO) {
+        super(taskTO);
+
+        final AjaxTextFieldPanel accountId = new 
AjaxTextFieldPanel("accountId", getString("accountId"),
+                new PropertyModel<String>(taskTO, "accountId"));
+        accountId.setEnabled(false);
+        profile.add(accountId);
+
+        final AjaxTextFieldPanel resource = new AjaxTextFieldPanel("resource", 
getString("resource"),
+                new PropertyModel<String>(taskTO, "resource"));
+        resource.setEnabled(false);
+        profile.add(resource);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
new file mode 100644
index 0000000..6418d61
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
@@ -0,0 +1,249 @@
+/*
+ * 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.pages;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.Constants;
+import 
org.apache.syncope.client.console.commons.status.AbstractStatusBeanProvider;
+import org.apache.syncope.client.console.commons.status.ConnObjectWrapper;
+import org.apache.syncope.client.console.commons.status.StatusBean;
+import org.apache.syncope.client.console.commons.status.StatusUtils;
+import org.apache.syncope.client.console.panels.ActionDataTablePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.wrap.AbstractWrappable;
+import org.apache.syncope.common.lib.wrap.SubjectKey;
+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.ISortableDataProvider;
+import 
org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.StringResourceModel;
+
+public class ProvisioningModalPage<T extends AbstractAttributableTO> extends 
AbstractStatusModalPage {
+
+    private static final long serialVersionUID = -4285220460543213901L;
+
+    private static final int ROWS_PER_PAGE = 10;
+
+    private final ResourceTO resourceTO;
+
+    private final Class<? extends AbstractAttributableTO> typeRef;
+
+    private final PageReference pageRef;
+
+    private final ModalWindow window;
+
+    private final StatusUtils statusUtils;
+
+    public ProvisioningModalPage(
+            final PageReference pageRef,
+            final ModalWindow window,
+            final ResourceTO resourceTO,
+            final Class<T> typeRef) {
+
+        super();
+
+        this.pageRef = pageRef;
+        this.window = window;
+        this.resourceTO = resourceTO;
+        this.typeRef = typeRef;
+
+        statusUtils = new StatusUtils((UserTO.class.isAssignableFrom(typeRef) 
? userRestClient : groupRestClient));
+
+        add(new Label("displayName", StringUtils.EMPTY));
+
+        final List<IColumn<StatusBean, String>> columns = new ArrayList<>();
+        columns.add(new PropertyColumn<StatusBean, String>(
+                new StringResourceModel("key", this, null, "Attributable key"),
+                "attributableKey", "attributableKey"));
+        columns.add(new PropertyColumn<StatusBean, String>(
+                new StringResourceModel("name", this, null, "Attributable 
name"),
+                "attributableName", "attributableName"));
+        columns.add(new PropertyColumn<StatusBean, String>(
+                new StringResourceModel("resourceName", this, null, "Resource 
name"),
+                "resourceName", "resourceName"));
+        columns.add(new PropertyColumn<StatusBean, String>(
+                new StringResourceModel("accountLink", this, null, "Account 
link"),
+                "accountLink", "accountLink"));
+        columns.add(new AbstractColumn<StatusBean, String>(
+                new StringResourceModel("status", this, null, "")) {
+
+                    private static final long serialVersionUID = 
-3503023501954863131L;
+
+                    @Override
+                    public String getCssClass() {
+                        return "action";
+                    }
+
+                    @Override
+                    public void populateItem(
+                            final Item<ICellPopulator<StatusBean>> cellItem,
+                            final String componentId,
+                            final IModel<StatusBean> model) {
+                                cellItem.
+                                
add(statusUtils.getStatusImagePanel(componentId, 
model.getObject().getStatus()));
+                            }
+                });
+
+        final ActionDataTablePanel<StatusBean, String> table = new 
ActionDataTablePanel<>(
+                "resourceDatatable",
+                columns,
+                (ISortableDataProvider<StatusBean, String>) new 
StatusBeanProvider(),
+                ROWS_PER_PAGE,
+                pageRef);
+
+        final String pageId = "Resources";
+
+        table.addAction(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                try {
+                    bulkAssociationAction(target, 
ResourceDeassociationActionType.UNLINK, table, columns);
+                } catch (Exception e) {
+                    LOG.error("Error unlinkink resources", e);
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    feedbackPanel.refresh(target);
+                }
+            }
+        }, ActionLink.ActionType.UNLINK, pageId);
+
+        table.addAction(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                try {
+                    bulkAssociationAction(target, 
ResourceDeassociationActionType.DEPROVISION, table, columns);
+                } catch (Exception e) {
+                    LOG.error("Error de-provisioning user", e);
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    feedbackPanel.refresh(target);
+                }
+            }
+        }, ActionLink.ActionType.DEPROVISION, pageId);
+
+        table.addAction(new ActionLink() {
+
+            private static final long serialVersionUID = -3722207913631435501L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                try {
+                    bulkAssociationAction(target, 
ResourceDeassociationActionType.UNASSIGN, table, columns);
+                } catch (Exception e) {
+                    LOG.error("Error unassigning resources", e);
+                    error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    feedbackPanel.refresh(target);
+                }
+            }
+        }, ActionLink.ActionType.UNASSIGN, pageId);
+
+        table.addCancelButton(window);
+
+        add(table);
+    }
+
+    private class StatusBeanProvider extends AbstractStatusBeanProvider {
+
+        private static final long serialVersionUID = 4287357360778016173L;
+
+        public StatusBeanProvider() {
+            super("accountLink");
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public List<StatusBean> getStatusBeans() {
+            final String fiql = 
SyncopeClient.getUserSearchConditionBuilder().hasResources(resourceTO.getKey()).query();
+
+            final List<T> subjects = new ArrayList<>();
+            if (UserTO.class.isAssignableFrom(typeRef)) {
+                subjects.addAll((List<T>) userRestClient.search(fiql, 1, 
ROWS_PER_PAGE, new SortParam<>("key", true)));
+            } else {
+                subjects.addAll((List<T>) groupRestClient.search(fiql, 1, 
ROWS_PER_PAGE, new SortParam<>("key", true)));
+            }
+
+            final List<ConnObjectWrapper> connObjects = 
statusUtils.getConnectorObjects(
+                    (List<AbstractSubjectTO>) subjects, 
Collections.<String>singleton(resourceTO.getKey()));
+
+            final List<StatusBean> statusBeans = new 
ArrayList<>(connObjects.size() + 1);
+            final LinkedHashMap<String, StatusBean> initialStatusBeanMap = new 
LinkedHashMap<>(connObjects.size());
+
+            for (ConnObjectWrapper entry : connObjects) {
+                final StatusBean statusBean = 
statusUtils.getStatusBean(entry.getAttributable(),
+                        entry.getResourceName(),
+                        entry.getConnObjectTO(),
+                        GroupTO.class.isAssignableFrom(typeRef));
+
+                initialStatusBeanMap.put(entry.getResourceName(), statusBean);
+                statusBeans.add(statusBean);
+            }
+
+            return statusBeans;
+        }
+    }
+
+    private void bulkAssociationAction(
+            final AjaxRequestTarget target,
+            final ResourceDeassociationActionType type,
+            final ActionDataTablePanel<StatusBean, String> table,
+            final List<IColumn<StatusBean, String>> columns) {
+
+        final List<StatusBean> beans = new ArrayList<>(table.getModelObject());
+        List<SubjectKey> subjectKeys = new ArrayList<>();
+        for (StatusBean bean : beans) {
+            LOG.debug("Selected bean {}", bean);
+            subjectKeys.add(AbstractWrappable.getInstance(SubjectKey.class, 
bean.getAttributableId()));
+        }
+
+        if (beans.isEmpty()) {
+            window.close(target);
+        } else {
+            final BulkActionResult res = 
resourceRestClient.bulkAssociationAction(
+                    resourceTO.getKey(), typeRef, type, subjectKeys);
+
+            ((BasePage) pageRef.getPage()).setModalResult(true);
+
+            setResponsePage(new BulkActionResultModalPage<>(window, beans, 
columns, res, "attributableKey"));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PushTaskModalPage.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PushTaskModalPage.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PushTaskModalPage.java
new file mode 100644
index 0000000..51852be
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/PushTaskModalPage.java
@@ -0,0 +1,135 @@
+/*
+ * 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.pages;
+
+import java.util.List;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.GroupSearchPanel;
+import org.apache.syncope.client.console.panels.UserSearchPanel;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
+import org.apache.syncope.common.lib.to.PushTaskTO;
+import org.apache.syncope.common.lib.to.SchedTaskTO;
+import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.model.Model;
+
+/**
+ * Modal window with Push Task form.
+ */
+public class PushTaskModalPage extends AbstractSyncTaskModalPage {
+
+    private static final long serialVersionUID = 2148403203517274669L;
+
+    private final UserSearchPanel userFilter;
+
+    private final GroupSearchPanel groupFilter;
+
+    private final AjaxCheckBoxPanel checkUserFilter;
+
+    private final AjaxCheckBoxPanel checkGroupFilter;
+
+    @Override
+    protected List<String> getSyncActions() {
+        return taskRestClient.getPushActionsClasses();
+    }
+
+    public PushTaskModalPage(final ModalWindow window, final PushTaskTO 
taskTO, final PageReference pageRef) {
+
+        super(window, taskTO, pageRef);
+
+        // set default Matching rule
+        ((DropDownChoice) 
matchingRule.getField()).setDefaultModelObject(taskTO.getMatchingRule() == null
+                ? MatchingRule.UPDATE
+                : taskTO.getMatchingRule());
+        profile.add(matchingRule);
+
+        // set default Unmatching rule
+        ((DropDownChoice) 
unmatchingRule.getField()).setDefaultModelObject(taskTO.getUnmatchingRule() == 
null
+                ? UnmatchingRule.ASSIGN
+                : taskTO.getUnmatchingRule());
+        profile.add(unmatchingRule);
+
+        final WebMarkupContainer filterContainer = new 
WebMarkupContainer("filterContainer");
+        filterContainer.setOutputMarkupId(true);
+
+        checkUserFilter = new AjaxCheckBoxPanel("checkUserFilter", 
"checkUserFilter",
+                new Model<>(taskTO.getUserFilter() != null));
+        filterContainer.add(checkUserFilter);
+
+        checkGroupFilter = new AjaxCheckBoxPanel("checkGroupFilter", 
"checkGroupFilter",
+                new Model<>(taskTO.getGroupFilter() != null));
+        filterContainer.add(checkGroupFilter);
+
+        userFilter = new 
UserSearchPanel.Builder("userFilter").fiql(taskTO.getUserFilter()).build();
+        userFilter.setEnabled(checkUserFilter.getModelObject());
+
+        filterContainer.add(userFilter);
+
+        groupFilter = new 
GroupSearchPanel.Builder("groupFilter").fiql(taskTO.getGroupFilter()).build();
+        groupFilter.setEnabled(checkGroupFilter.getModelObject());
+        filterContainer.add(groupFilter);
+
+        checkUserFilter.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                userFilter.setEnabled(checkUserFilter.getModelObject());
+                target.add(filterContainer);
+            }
+        });
+
+        checkGroupFilter.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                groupFilter.setEnabled(checkGroupFilter.getModelObject());
+                target.add(filterContainer);
+            }
+        });
+
+        profile.add(filterContainer);
+    }
+
+    @Override
+    public void submitAction(final SchedTaskTO taskTO) {
+        setFilters((PushTaskTO) taskTO);
+        if (taskTO.getKey() > 0) {
+            taskRestClient.updateSchedTask((PushTaskTO) taskTO);
+        } else {
+            taskRestClient.createSchedTask((PushTaskTO) taskTO);
+        }
+    }
+
+    private void setFilters(final PushTaskTO pushTaskTO) {
+        // set user filter if enabled
+        pushTaskTO.setUserFilter(checkUserFilter.getModelObject() ? 
userFilter.buildFIQL() : null);
+        // set group filter if enabled
+        pushTaskTO.setGroupFilter(checkGroupFilter.getModelObject() ? 
groupFilter.buildFIQL() : null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportExecResultDownloadModalPage.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportExecResultDownloadModalPage.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportExecResultDownloadModalPage.java
new file mode 100644
index 0000000..c6b57d2
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportExecResultDownloadModalPage.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.pages;
+
+import java.util.Arrays;
+import org.apache.syncope.client.console.commons.Constants;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.common.lib.types.ReportExecExportFormat;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.form.IChoiceRenderer;
+import org.apache.wicket.model.Model;
+
+public class ReportExecResultDownloadModalPage extends BaseModalPage {
+
+    private static final long serialVersionUID = 3163146190501510888L;
+
+    public ReportExecResultDownloadModalPage(final ModalWindow window, final 
PageReference callerPageRef) {
+
+        final AjaxDropDownChoicePanel<ReportExecExportFormat> format =
+                new AjaxDropDownChoicePanel<>("format", "format", new 
Model<ReportExecExportFormat>());
+
+        format.setChoices(Arrays.asList(ReportExecExportFormat.values()));
+
+        format.setChoiceRenderer(new IChoiceRenderer<ReportExecExportFormat>() 
{
+
+            private static final long serialVersionUID = -3941271550163141339L;
+
+            @Override
+            public Object getDisplayValue(final ReportExecExportFormat object) 
{
+                return object.name();
+            }
+
+            @Override
+            public String getIdValue(final ReportExecExportFormat object, 
final int index) {
+
+                return object.name();
+            }
+        });
+
+        format.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                format.getField();
+
+                ((ReportModalPage) 
callerPageRef.getPage()).setExportFormat(format.getField().getModelObject());
+                window.close(target);
+            }
+        });
+        add(format);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportModalPage.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportModalPage.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportModalPage.java
new file mode 100644
index 0000000..0ef7c6a
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportModalPage.java
@@ -0,0 +1,640 @@
+/*
+ * 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.pages;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.DateFormatROModel;
+import org.apache.syncope.client.console.commons.HttpResourceStream;
+import 
org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import 
org.apache.syncope.client.console.wicket.ajax.form.AbstractAjaxDownloadBehavior;
+import 
org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
+import 
org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
+import 
org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
+import org.apache.syncope.client.console.wicket.markup.html.CrontabContainer;
+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.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.report.AbstractReportletConf;
+import org.apache.syncope.common.lib.report.ReportletConf;
+import org.apache.syncope.common.lib.to.ReportExecTO;
+import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.common.lib.types.ReportExecExportFormat;
+import org.apache.syncope.common.lib.types.ReportExecStatus;
+import org.apache.wicket.Component;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+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.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import 
org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+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.sort.SortOrder;
+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.extensions.markup.html.repeater.util.SortableDataProvider;
+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.form.IChoiceRenderer;
+import org.apache.wicket.markup.html.form.ListChoice;
+import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.util.resource.IResourceStream;
+import org.springframework.util.StringUtils;
+
+public class ReportModalPage extends BaseModalPage {
+
+    private static final long serialVersionUID = -5747628615211127644L;
+
+    private static final String ADD_BUTTON_ID = "addButton";
+
+    private static final String EDIT_BUTTON_ID = "editButton";
+
+    private static final String REMOVE_BUTTON_ID = "removeButton";
+
+    private static final String UP_BUTTON_ID = "upButton";
+
+    private static final String DOWN_BUTTON_ID = "downButton";
+
+    private static final int EXEC_EXPORT_WIN_HEIGHT = 100;
+
+    private static final int EXEC_EXPORT_WIN_WIDTH = 400;
+
+    private static final int REPORTLET_CONF_WIN_HEIGHT = 500;
+
+    private static final int REPORTLET_CONF_WIN_WIDTH = 800;
+
+    private final ReportTO reportTO;
+
+    private final Form<ReportTO> form;
+
+    private ReportExecExportFormat exportFormat;
+
+    private long exportExecId;
+
+    private AbstractReportletConf modalReportletConf;
+
+    private String modalReportletConfOldName;
+
+    private ListChoice<AbstractReportletConf> reportlets;
+
+    public ReportModalPage(final ModalWindow window, final ReportTO reportTO, 
final PageReference callerPageRef) {
+        super();
+        this.reportTO = reportTO;
+
+        form = new Form<ReportTO>(FORM);
+        form.setModel(new CompoundPropertyModel<ReportTO>(reportTO));
+        add(form);
+
+        setupProfile();
+        setupExecutions();
+
+        final CrontabContainer crontab = new CrontabContainer("crontab", new 
PropertyModel<String>(reportTO,
+                "cronExpression"), reportTO.getCronExpression());
+        form.add(crontab);
+
+        final AjaxButton submit =
+                new ClearIndicatingAjaxButton(APPLY, new ResourceModel(APPLY), 
getPageReference()) {
+
+                    private static final long serialVersionUID = 
-958724007591692537L;
+
+                    @Override
+                    protected void onSubmitInternal(final AjaxRequestTarget 
target, final Form<?> form) {
+                        ReportTO toSubmit = (ReportTO) form.getModelObject();
+                        
toSubmit.setCronExpression(StringUtils.hasText(toSubmit.getCronExpression())
+                                        ? crontab.getCronExpression()
+                                        : null);
+
+                        try {
+                            if (toSubmit.getKey() > 0) {
+                                reportRestClient.update(toSubmit);
+                            } else {
+                                reportRestClient.create(toSubmit);
+                            }
+
+                            ((BasePage) 
callerPageRef.getPage()).setModalResult(true);
+
+                            window.close(target);
+                        } catch (SyncopeClientException e) {
+                            LOG.error("While creating or updating report", e);
+                            error(getString(Constants.ERROR) + ": " + 
e.getMessage());
+                            feedbackPanel.refresh(target);
+                        }
+                    }
+
+                    @Override
+                    protected void onError(final AjaxRequestTarget target, 
final Form<?> form) {
+                        feedbackPanel.refresh(target);
+                    }
+                };
+
+        if (reportTO.getKey() > 0) {
+            MetaDataRoleAuthorizationStrategy.authorize(submit, RENDER,
+                    xmlRolesReader.getEntitlement("Reports", "update"));
+        } else {
+            MetaDataRoleAuthorizationStrategy.authorize(submit, RENDER,
+                    xmlRolesReader.getEntitlement("Reports", "create"));
+        }
+
+        form.add(submit);
+
+        final AjaxButton cancel =
+                new ClearIndicatingAjaxButton(CANCEL, new 
ResourceModel(CANCEL), getPageReference()) {
+
+                    private static final long serialVersionUID = 
-958724007591692537L;
+
+                    @Override
+                    protected void onSubmitInternal(final AjaxRequestTarget 
target, final Form<?> form) {
+                        window.close(target);
+                    }
+                };
+
+        cancel.setDefaultFormProcessing(false);
+        form.add(cancel);
+    }
+
+    private void setupProfile() {
+        final WebMarkupContainer profile = new WebMarkupContainer("profile");
+        profile.setOutputMarkupId(true);
+        form.add(profile);
+
+        final ModalWindow reportletConfWin = new 
ModalWindow("reportletConfWin");
+        reportletConfWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        reportletConfWin.setCookieName("reportlet-conf-win-modal");
+        reportletConfWin.setInitialHeight(REPORTLET_CONF_WIN_HEIGHT);
+        reportletConfWin.setInitialWidth(REPORTLET_CONF_WIN_WIDTH);
+        reportletConfWin.setWindowClosedCallback(new 
ModalWindow.WindowClosedCallback() {
+
+            private static final long serialVersionUID = 8804221891699487139L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                int foundIdx = -1;
+                if (modalReportletConfOldName != null) {
+                    for (int i = 0; i < reportTO.getReportletConfs().size() && 
foundIdx == -1; i++) {
+                        if 
(reportTO.getReportletConfs().get(i).getName().equals(modalReportletConfOldName))
 {
+                            foundIdx = i;
+                        }
+                    }
+                }
+                if (modalReportletConf != null) {
+                    if (foundIdx == -1) {
+                        reportTO.getReportletConfs().add(modalReportletConf);
+                    } else {
+                        reportTO.getReportletConfs().set(foundIdx, 
modalReportletConf);
+                    }
+                }
+
+                target.add(reportlets);
+            }
+        });
+        add(reportletConfWin);
+
+        final Label idLabel = new Label("idLabel", new ResourceModel("key"));
+        profile.add(idLabel);
+
+        final AjaxTextFieldPanel key =
+                new AjaxTextFieldPanel("key", getString("key"), new 
PropertyModel<String>(reportTO, "key"));
+        key.setEnabled(false);
+        profile.add(key);
+
+        final Label nameLabel = new Label("nameLabel", new 
ResourceModel("name"));
+        profile.add(nameLabel);
+
+        final AjaxTextFieldPanel name =
+                new AjaxTextFieldPanel("name", getString("name"), new 
PropertyModel<String>(reportTO, "name"));
+        profile.add(name);
+
+        final AjaxTextFieldPanel lastExec = new AjaxTextFieldPanel("lastExec", 
getString("lastExec"),
+                new DateFormatROModel(new PropertyModel<String>(reportTO, 
"lastExec")));
+        lastExec.setEnabled(false);
+        profile.add(lastExec);
+
+        final AjaxTextFieldPanel nextExec = new AjaxTextFieldPanel("nextExec", 
getString("nextExec"),
+                new DateFormatROModel(new PropertyModel<String>(reportTO, 
"nextExec")));
+        nextExec.setEnabled(false);
+        profile.add(nextExec);
+
+        reportlets = new ListChoice<AbstractReportletConf>("reportletConfs", 
new Model<AbstractReportletConf>(),
+                reportTO.getReportletConfs(), new 
IChoiceRenderer<ReportletConf>() {
+
+                    private static final long serialVersionUID = 
1048000918946220007L;
+
+                    @Override
+                    public Object getDisplayValue(final ReportletConf object) {
+                        return object.getName();
+                    }
+
+                    @Override
+                    public String getIdValue(final ReportletConf object, final 
int index) {
+                        return object.getName();
+                    }
+                }) {
+
+                    private static final long serialVersionUID = 
4022366881854379834L;
+
+                    @Override
+                    protected CharSequence getDefaultChoice(final String 
selectedValue) {
+                        return null;
+                    }
+                };
+
+        reportlets.setNullValid(true);
+        profile.add(reportlets);
+        reportlets.add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                target.add(reportlets);
+            }
+        });
+
+        profile.add(new AjaxLink<Void>(ADD_BUTTON_ID) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                reportletConfWin.setPageCreator(new ModalWindow.PageCreator() {
+
+                    private static final long serialVersionUID = 
-7834632442532690940L;
+
+                    @Override
+                    public Page createPage() {
+                        modalReportletConfOldName = null;
+                        modalReportletConf = null;
+                        return new ReportletConfModalPage(null, 
reportletConfWin,
+                                ReportModalPage.this.getPageReference());
+                    }
+                });
+                reportletConfWin.show(target);
+            }
+        });
+
+        profile.add(new AjaxLink<Void>(EDIT_BUTTON_ID) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                if (reportlets.getModelObject() != null) {
+                    reportletConfWin.setPageCreator(new 
ModalWindow.PageCreator() {
+
+                        private static final long serialVersionUID = 
-7834632442532690940L;
+
+                        @Override
+                        public Page createPage() {
+                            modalReportletConfOldName = 
reportlets.getModelObject().getName();
+                            modalReportletConf = null;
+                            return new 
ReportletConfModalPage(reportlets.getModelObject(), reportletConfWin,
+                                    ReportModalPage.this.getPageReference());
+                        }
+                    });
+                    reportletConfWin.show(target);
+                }
+            }
+        });
+
+        profile.add(new AjaxLink<Void>(REMOVE_BUTTON_ID) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                
reportTO.getReportletConfs().remove(reportlets.getModelObject());
+                reportlets.setModelObject(null);
+                target.add(reportlets);
+            }
+
+            @Override
+            protected void updateAjaxAttributes(final AjaxRequestAttributes 
attributes) {
+                if (reportlets.getModelObject() != null) {
+
+                    super.updateAjaxAttributes(attributes);
+
+                    final AjaxCallListener 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);
+                }
+            }
+        });
+
+        profile.add(new AjaxLink<Void>(UP_BUTTON_ID) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                if (reportlets.getModelObject() != null) {
+                    moveUp(reportlets.getModelObject());
+                    target.add(reportlets);
+                }
+            }
+        });
+
+        profile.add(new AjaxLink<Void>(DOWN_BUTTON_ID) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                if (reportlets.getModelObject() != null) {
+                    moveDown(reportlets.getModelObject());
+                    target.add(reportlets);
+                }
+            }
+        });
+    }
+
+    private void moveUp(final AbstractReportletConf item) {
+        final List<AbstractReportletConf> list = reportTO.getReportletConfs();
+        int newPosition = list.indexOf(item) - 1;
+        if (newPosition > -1) {
+            list.remove(item);
+            list.add(newPosition, item);
+        }
+    }
+
+    private void moveDown(final AbstractReportletConf item) {
+        final List<AbstractReportletConf> list = reportTO.getReportletConfs();
+        int newPosition = list.indexOf(item) + 1;
+        if (newPosition < list.size()) {
+            list.remove(item);
+            list.add(newPosition, item);
+        }
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private void setupExecutions() {
+        final WebMarkupContainer executions = new 
WebMarkupContainer("executionContainer");
+        executions.setOutputMarkupId(true);
+        form.add(executions);
+
+        final ModalWindow reportExecMessageWin = new 
ModalWindow("reportExecMessageWin");
+        reportExecMessageWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        reportExecMessageWin.setCookieName("report-exec-message-win-modal");
+        add(reportExecMessageWin);
+
+        final ModalWindow reportExecExportWin = new 
ModalWindow("reportExecExportWin");
+        reportExecExportWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        reportExecExportWin.setCookieName("report-exec-export-win-modal");
+        reportExecExportWin.setInitialHeight(EXEC_EXPORT_WIN_HEIGHT);
+        reportExecExportWin.setInitialWidth(EXEC_EXPORT_WIN_WIDTH);
+        reportExecExportWin.setWindowClosedCallback(new 
ModalWindow.WindowClosedCallback() {
+
+            private static final long serialVersionUID = 8804221891699487139L;
+
+            @Override
+            public void onClose(final AjaxRequestTarget target) {
+                AjaxExportDownloadBehavior behavior = new 
AjaxExportDownloadBehavior(ReportModalPage.this.exportFormat,
+                        ReportModalPage.this.exportExecId);
+                executions.add(behavior);
+                behavior.initiate(target);
+            }
+        });
+        add(reportExecExportWin);
+
+        final List<IColumn> columns = new ArrayList<IColumn>();
+        columns.add(new PropertyColumn(new ResourceModel("key"), "key", 
"key"));
+        columns.add(new DatePropertyColumn(new ResourceModel("startDate"), 
"startDate", "startDate"));
+        columns.add(new DatePropertyColumn(new ResourceModel("endDate"), 
"endDate", "endDate"));
+        columns.add(new PropertyColumn(new ResourceModel("status"), "status", 
"status"));
+        columns.add(new ActionColumn<ReportExecTO, String>(new 
ResourceModel("actions", "")) {
+
+            private static final long serialVersionUID = 2054811145491901166L;
+
+            @Override
+            public ActionLinksPanel getActions(final String componentId, final 
IModel<ReportExecTO> model) {
+
+                final ReportExecTO taskExecutionTO = model.getObject();
+
+                final ActionLinksPanel panel = new 
ActionLinksPanel(componentId, model, getPageReference());
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = 
-3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        reportExecMessageWin.setPageCreator(new 
ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = 
-7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                return new 
ExecMessageModalPage(model.getObject().getMessage());
+                            }
+                        });
+                        reportExecMessageWin.show(target);
+                    }
+                }, ActionLink.ActionType.EDIT, "Reports", 
StringUtils.hasText(model.getObject().getMessage()));
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = 
-3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        reportExecExportWin.setPageCreator(new 
ModalWindow.PageCreator() {
+
+                            private static final long serialVersionUID = 
-7834632442532690940L;
+
+                            @Override
+                            public Page createPage() {
+                                ReportModalPage.this.exportExecId = 
model.getObject().getKey();
+                                return new 
ReportExecResultDownloadModalPage(reportExecExportWin,
+                                        
ReportModalPage.this.getPageReference());
+                            }
+                        });
+                        reportExecExportWin.show(target);
+                    }
+                }, ActionLink.ActionType.EXPORT, "Reports", 
ReportExecStatus.SUCCESS.name().equals(
+                        model.getObject().getStatus()));
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = 
-3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        try {
+                            
reportRestClient.deleteExecution(taskExecutionTO.getKey());
+
+                            reportTO.getExecutions().remove(taskExecutionTO);
+
+                            info(getString(Constants.OPERATION_SUCCEEDED));
+                        } catch (SyncopeClientException scce) {
+                            error(scce.getMessage());
+                        }
+
+                        feedbackPanel.refresh(target);
+                        target.add(executions);
+                    }
+                }, ActionLink.ActionType.DELETE, "Reports");
+
+                return panel;
+            }
+
+            @Override
+            public Component getHeader(final String componentId) {
+                final ActionLinksPanel panel = new 
ActionLinksPanel(componentId, new Model(), getPageReference());
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = 
-7978723352517770644L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        if (target != null) {
+                            final ReportTO currentReportTO = reportTO.getKey() 
== 0
+                                    ? reportTO
+                                    : reportRestClient.read(reportTO.getKey());
+                            reportTO.getExecutions().clear();
+                            
reportTO.getExecutions().addAll(currentReportTO.getExecutions());
+                            final AjaxFallbackDefaultDataTable currentTable =
+                                    new 
AjaxFallbackDefaultDataTable("executionsTable", columns,
+                                            new 
ReportExecutionsProvider(reportTO), 10);
+                            currentTable.setOutputMarkupId(true);
+                            target.add(currentTable);
+                            executions.addOrReplace(currentTable);
+                        }
+                    }
+                }, ActionLink.ActionType.RELOAD, TASKS, "list");
+
+                return panel;
+            }
+        });
+
+        final AjaxFallbackDefaultDataTable table = new 
AjaxFallbackDefaultDataTable("executionsTable", columns,
+                new ReportExecutionsProvider(reportTO), 10);
+        executions.add(table);
+    }
+
+    public void setExportFormat(final ReportExecExportFormat exportFormat) {
+        this.exportFormat = exportFormat;
+    }
+
+    public void setModalReportletConf(final AbstractReportletConf 
modalReportletConf) {
+        this.modalReportletConf = modalReportletConf;
+    }
+
+    private static class ReportExecutionsProvider extends 
SortableDataProvider<ReportExecTO, String> {
+
+        private static final long serialVersionUID = 2118096121691420539L;
+
+        private final SortableDataProviderComparator<ReportExecTO> comparator;
+
+        private final ReportTO reportTO;
+
+        public ReportExecutionsProvider(final ReportTO reportTO) {
+            super();
+            this.reportTO = reportTO;
+            setSort("startDate", SortOrder.DESCENDING);
+            comparator = new 
SortableDataProviderComparator<ReportExecTO>(this);
+        }
+
+        @Override
+        public Iterator<ReportExecTO> iterator(final long first, final long 
count) {
+
+            List<ReportExecTO> list = reportTO.getExecutions();
+
+            Collections.sort(list, comparator);
+
+            return list.subList((int) first, (int) first + (int) 
count).iterator();
+        }
+
+        @Override
+        public long size() {
+            return reportTO.getExecutions().size();
+        }
+
+        @Override
+        public IModel<ReportExecTO> model(final ReportExecTO taskExecution) {
+
+            return new AbstractReadOnlyModel<ReportExecTO>() {
+
+                private static final long serialVersionUID = 
7485475149862342421L;
+
+                @Override
+                public ReportExecTO getObject() {
+                    return taskExecution;
+                }
+            };
+        }
+    }
+
+    private class AjaxExportDownloadBehavior extends 
AbstractAjaxDownloadBehavior {
+
+        private static final long serialVersionUID = 3109256773218160485L;
+
+        private final ReportExecExportFormat exportFormat;
+
+        private final long exportExecId;
+
+        private HttpResourceStream stream;
+
+        public AjaxExportDownloadBehavior(final ReportExecExportFormat 
exportFormat, final long exportExecId) {
+            super();
+            this.exportFormat = exportFormat;
+            this.exportExecId = exportExecId;
+        }
+
+        private void createResourceStream() {
+            if (stream == null) {
+                stream = new 
HttpResourceStream(reportRestClient.exportExecutionResult(exportExecId, 
exportFormat));
+            }
+        }
+
+        @Override
+        protected String getFileName() {
+            createResourceStream();
+            return stream == null
+                    ? null
+                    : stream.getFilename();
+        }
+
+        @Override
+        protected IResourceStream getResourceStream() {
+            createResourceStream();
+            return stream;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportletConfModalPage.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportletConfModalPage.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportletConfModalPage.java
new file mode 100644
index 0000000..36560b0
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/ReportletConfModalPage.java
@@ -0,0 +1,362 @@
+/*
+ * 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.pages;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.GroupSearchPanel;
+import org.apache.syncope.client.console.panels.UserSearchPanel;
+import 
org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
+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.client.console.wicket.markup.html.form.AjaxPalettePanel;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.CheckBoxMultipleChoiceFieldPanel;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.DateTimeFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
+import 
org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.annotation.FormAttributeField;
+import org.apache.syncope.common.lib.report.AbstractReportletConf;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.wicket.Component;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+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.DropDownChoice;
+import org.apache.wicket.markup.html.form.Form;
+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.model.util.ListModel;
+import org.apache.wicket.util.visit.IVisit;
+import org.apache.wicket.util.visit.IVisitor;
+import org.springframework.beans.BeanWrapper;
+import org.springframework.beans.PropertyAccessorFactory;
+import org.springframework.util.ClassUtils;
+
+public class ReportletConfModalPage extends BaseModalPage {
+
+    private static final long serialVersionUID = 3910027601200382958L;
+
+    private static final String[] EXCLUDE_PROPERTIES =
+            new String[] { "serialVersionUID", "class", "name", 
"reportletClassName" };
+
+    private AbstractReportletConf reportletConf;
+
+    private final AjaxTextFieldPanel name;
+
+    private WebMarkupContainer propertiesContainer;
+
+    private ListView<String> propView;
+
+    public ReportletConfModalPage(final AbstractReportletConf reportletConf, 
final ModalWindow window,
+            final PageReference pageRef) {
+
+        this.reportletConf = reportletConf;
+
+        final Form form = new Form(FORM);
+        add(form);
+
+        propertiesContainer = new WebMarkupContainer("container");
+        propertiesContainer.setOutputMarkupId(true);
+        form.add(propertiesContainer);
+
+        name = new AjaxTextFieldPanel("name", "name", this.reportletConf == 
null
+                ? new Model<String>()
+                : new PropertyModel<String>(this.reportletConf, "name"));
+        name.setOutputMarkupId(true);
+        name.addRequiredLabel();
+        form.add(name);
+
+        final AjaxDropDownChoicePanel<String> reportletClass = new 
AjaxDropDownChoicePanel<String>("reportletClass",
+                "reportletClass", new IModel<String>() {
+
+                    private static final long serialVersionUID = 
-2316468110411802130L;
+
+                    @Override
+                    public String getObject() {
+                        return ReportletConfModalPage.this.reportletConf == 
null
+                                ? null
+                                : 
ReportletConfModalPage.this.reportletConf.getClass().getName();
+                    }
+
+                    @Override
+                    public void setObject(final String object) {
+                        try {
+                            Class<?> reportletClass = Class.forName(object);
+                            ReportletConfModalPage.this.reportletConf = 
(AbstractReportletConf) reportletClass.
+                            newInstance();
+                            propertiesContainer.replace(buildPropView());
+                        } catch (Exception e) {
+                            LOG.error("Cannot find or initialize {}", object, 
e);
+                        }
+                    }
+
+                    @Override
+                    public void detach() {
+                    }
+                });
+        reportletClass.setStyleSheet("long_dynamicsize");
+        reportletClass.setChoices(reportRestClient.getReportletConfClasses());
+        ((DropDownChoice) reportletClass.getField()).setNullValid(true);
+        reportletClass.addRequiredLabel();
+        reportletClass.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = 5538299138211283825L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                ((DropDownChoice) 
reportletClass.getField()).setNullValid(false);
+                target.add(reportletClass.getField());
+                target.add(propertiesContainer);
+            }
+        });
+        form.add(reportletClass);
+
+        propertiesContainer.add(buildPropView());
+
+        final AjaxButton submit = new AjaxButton(APPLY, new 
ResourceModel(APPLY)) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
+                final BeanWrapper wrapper = PropertyAccessorFactory.
+                        
forBeanPropertyAccess(ReportletConfModalPage.this.reportletConf);
+                wrapper.setPropertyValue("name", name.getField().getInput());
+
+                // Iterate over properties in order to find UserSearchPanel 
instances and manually update
+                // this.reportletConf with select search criteria - this is 
needed because UserSearchPanel
+                // does not comply with usual Wicket model paradigm.
+                ReportletConfModalPage.this.propView.visitChildren(new 
IVisitor<Component, Void>() {
+
+                    @Override
+                    public void component(final Component component, final 
IVisit<Void> ivisit) {
+                        if (component instanceof UserSearchPanel) {
+                            // using component.getDefaultModelObjectAsString() 
to fetch field name (set above)
+                            
wrapper.setPropertyValue(component.getDefaultModelObjectAsString(),
+                                    ((UserSearchPanel) component).buildFIQL());
+                        }
+                    }
+                });
+
+                ((ReportModalPage) 
pageRef.getPage()).setModalReportletConf(ReportletConfModalPage.this.reportletConf);
+                window.close(target);
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
+                feedbackPanel.refresh(target);
+            }
+        };
+        form.add(submit);
+
+        final AjaxButton cancel = new ClearIndicatingAjaxButton(CANCEL, new 
ResourceModel(CANCEL), pageRef) {
+
+            private static final long serialVersionUID = -958724007591692537L;
+
+            @Override
+            protected void onSubmitInternal(final AjaxRequestTarget target, 
final Form<?> form) {
+                window.close(target);
+            }
+        };
+
+        cancel.setDefaultFormProcessing(false);
+        form.add(cancel);
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private FieldPanel buildSinglePanel(final Class<?> type, final String 
fieldName, final String id) {
+        FieldPanel result = null;
+        PropertyModel model = new 
PropertyModel(ReportletConfModalPage.this.reportletConf, fieldName);
+        if (ClassUtils.isAssignable(Boolean.class, type)) {
+            result = new AjaxCheckBoxPanel(id, fieldName, model);
+        } else if (ClassUtils.isAssignable(Number.class, type)) {
+            result = new SpinnerFieldPanel<Number>(id, fieldName,
+                    (Class<Number>) 
ClassUtils.resolvePrimitiveIfNecessary(type), model, null, null);
+        } else if (Date.class.equals(type)) {
+            result = new DateTimeFieldPanel(id, fieldName, model, 
SyncopeConstants.DEFAULT_DATE_PATTERN);
+        } else if (type.isEnum()) {
+            result = new AjaxDropDownChoicePanel(id, fieldName, 
model).setChoices(
+                    Arrays.asList(type.getEnumConstants()));
+        }
+
+        // treat as String if nothing matched above
+        if (result == null) {
+            result = new AjaxTextFieldPanel(id, fieldName, model);
+        }
+
+        return result;
+    }
+
+    private ListView<String> buildPropView() {
+        LoadableDetachableModel<List<String>> propViewModel = new 
LoadableDetachableModel<List<String>>() {
+
+            private static final long serialVersionUID = 5275935387613157437L;
+
+            @Override
+            protected List<String> load() {
+                List<String> result = new ArrayList<String>();
+                if (ReportletConfModalPage.this.reportletConf != null) {
+                    for (Field field : 
ReportletConfModalPage.this.reportletConf.getClass().getDeclaredFields()) {
+                        if (!ArrayUtils.contains(EXCLUDE_PROPERTIES, 
field.getName())) {
+                            result.add(field.getName());
+                        }
+                    }
+                }
+
+                return result;
+            }
+        };
+
+        propView = new ListView<String>("propView", propViewModel) {
+
+            private static final long serialVersionUID = 9101744072914090143L;
+
+            @SuppressWarnings({ "unchecked", "rawtypes" })
+            @Override
+            protected void populateItem(final ListItem<String> item) {
+                final String fieldName = item.getModelObject();
+
+                Label label = new Label("key", fieldName);
+                item.add(label);
+
+                Field field = null;
+                try {
+                    field = 
ReportletConfModalPage.this.reportletConf.getClass().getDeclaredField(fieldName);
+                } catch (Exception e) {
+                    LOG.error("Could not find field {} in class {}",
+                            fieldName, 
ReportletConfModalPage.this.reportletConf.getClass(), e);
+                }
+                if (field == null) {
+                    return;
+                }
+
+                FormAttributeField annotation = 
field.getAnnotation(FormAttributeField.class);
+
+                BeanWrapper wrapper = PropertyAccessorFactory.
+                        
forBeanPropertyAccess(ReportletConfModalPage.this.reportletConf);
+
+                Panel panel;
+
+                if (String.class.equals(field.getType()) && annotation != null 
&& annotation.userSearch()) {
+                    panel = new UserSearchPanel.Builder("value").
+                            fiql((String) 
wrapper.getPropertyValue(fieldName)).required(false).build();
+                    // This is needed in order to manually update 
this.reportletConf with search panel selections
+                    panel.setDefaultModel(new Model<String>(fieldName));
+                } else if (String.class.equals(field.getType()) && annotation 
!= null && annotation.groupSearch()) {
+                    panel = new GroupSearchPanel.Builder("value").
+                            fiql((String) 
wrapper.getPropertyValue(fieldName)).required(false).build();
+                    // This is needed in order to manually update 
this.reportletConf with search panel selections
+                    panel.setDefaultModel(new Model<String>(fieldName));
+                } else if (List.class.equals(field.getType())) {
+                    Class<?> listItemType = String.class;
+                    if (field.getGenericType() instanceof ParameterizedType) {
+                        listItemType =
+                                (Class<?>) ((ParameterizedType) 
field.getGenericType()).getActualTypeArguments()[0];
+                    }
+
+                    if (listItemType.equals(String.class) && annotation != 
null) {
+                        List<String> choices;
+                        switch (annotation.schema()) {
+                            case UserPlainSchema:
+                                choices = 
schemaRestClient.getPlainSchemaNames(AttributableType.USER);
+                                break;
+
+                            case UserDerivedSchema:
+                                choices = 
schemaRestClient.getDerSchemaNames(AttributableType.USER);
+                                break;
+
+                            case UserVirtualSchema:
+                                choices = 
schemaRestClient.getVirSchemaNames(AttributableType.USER);
+                                break;
+
+                            case GroupPlainSchema:
+                                choices = 
schemaRestClient.getPlainSchemaNames(AttributableType.GROUP);
+                                break;
+
+                            case GroupDerivedSchema:
+                                choices = 
schemaRestClient.getDerSchemaNames(AttributableType.GROUP);
+                                break;
+
+                            case GroupVirtualSchema:
+                                choices = 
schemaRestClient.getVirSchemaNames(AttributableType.GROUP);
+                                break;
+
+                            case MembershipPlainSchema:
+                                choices = 
schemaRestClient.getPlainSchemaNames(AttributableType.MEMBERSHIP);
+                                break;
+
+                            case MembershipDerivedSchema:
+                                choices = 
schemaRestClient.getDerSchemaNames(AttributableType.MEMBERSHIP);
+                                break;
+
+                            case MembershipVirtualSchema:
+                                choices = 
schemaRestClient.getVirSchemaNames(AttributableType.MEMBERSHIP);
+                                break;
+
+                            default:
+                                choices = Collections.emptyList();
+                        }
+
+                        panel = new AjaxPalettePanel("value", new 
PropertyModel<List<String>>(
+                                ReportletConfModalPage.this.reportletConf, 
fieldName), new ListModel<String>(choices),
+                                true);
+                    } else if (listItemType.isEnum()) {
+                        panel = new CheckBoxMultipleChoiceFieldPanel("value", 
new PropertyModel(
+                                ReportletConfModalPage.this.reportletConf, 
fieldName),
+                                new 
ListModel(Arrays.asList(listItemType.getEnumConstants())));
+                    } else {
+                        if (((List) 
wrapper.getPropertyValue(fieldName)).isEmpty()) {
+                            ((List) 
wrapper.getPropertyValue(fieldName)).add(null);
+                        }
+
+                        panel = new MultiFieldPanel("value", new 
PropertyModel<List>(
+                                ReportletConfModalPage.this.reportletConf, 
fieldName),
+                                buildSinglePanel(field.getType(), fieldName, 
"panel"));
+                    }
+                } else {
+                    panel = buildSinglePanel(field.getType(), fieldName, 
"value");
+                }
+
+                item.add(panel);
+            }
+        };
+
+        return propView;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
----------------------------------------------------------------------
diff --git 
a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
new file mode 100644
index 0000000..e484701
--- /dev/null
+++ 
b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
@@ -0,0 +1,412 @@
+/*
+ * 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.pages;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.PreferenceManager;
+import 
org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.panels.LoggerCategoryPanel;
+import org.apache.syncope.client.console.panels.SelectedEventsPanel;
+import org.apache.syncope.client.console.rest.LoggerRestClient;
+import 
org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
+import 
org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
+import 
org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
+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.EventCategoryTO;
+import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+import org.apache.wicket.Component;
+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.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.event.IEvent;
+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.sort.SortOrder;
+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.extensions.markup.html.repeater.util.SortableDataProvider;
+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.model.AbstractReadOnlyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.model.util.ListModel;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * Auditing and Reporting.
+ */
+public class Reports extends BasePage {
+
+    private static final long serialVersionUID = -2071214196989178694L;
+
+    private static final int WIN_HEIGHT = 500;
+
+    private static final int WIN_WIDTH = 700;
+
+    @SpringBean
+    private LoggerRestClient loggerRestClient;
+
+    @SpringBean
+    private PreferenceManager prefMan;
+
+    private WebMarkupContainer reportContainer;
+
+    private WebMarkupContainer auditContainer;
+
+    private int paginatorRows;
+
+    private final ModalWindow window;
+
+    public Reports(final PageParameters parameters) {
+        super(parameters);
+
+        window = new ModalWindow("reportWin");
+        window.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+        window.setInitialHeight(WIN_HEIGHT);
+        window.setInitialWidth(WIN_WIDTH);
+        window.setCookieName("view-report-win");
+        add(window);
+
+        setupReport();
+        setupAudit();
+    }
+
+    private void setupReport() {
+        reportContainer = new WebMarkupContainer("reportContainer");
+        setWindowClosedCallback(window, reportContainer);
+
+        MetaDataRoleAuthorizationStrategy.authorize(reportContainer, RENDER,
+                xmlRolesReader.getEntitlement("Reports", "list"));
+
+        paginatorRows = prefMan.getPaginatorRows(getRequest(), 
Constants.PREF_REPORT_PAGINATOR_ROWS);
+
+        List<IColumn<ReportTO, String>> columns = new ArrayList<>();
+        columns.add(new PropertyColumn<ReportTO, String>(new 
ResourceModel("key"), "key", "key"));
+        columns.add(new PropertyColumn<ReportTO, String>(new 
ResourceModel("name"), "name", "name"));
+        columns.add(new DatePropertyColumn<ReportTO>(new 
ResourceModel("lastExec"), "lastExec", "lastExec"));
+        columns.add(new DatePropertyColumn<ReportTO>(new 
ResourceModel("nextExec"), "nextExec", "nextExec"));
+        columns.add(new DatePropertyColumn<ReportTO>(new 
ResourceModel("startDate"), "startDate", "startDate"));
+        columns.add(new DatePropertyColumn<ReportTO>(new 
ResourceModel("endDate"), "endDate", "endDate"));
+        columns.add(new PropertyColumn<ReportTO, String>(
+                new ResourceModel("latestExecStatus"), "latestExecStatus", 
"latestExecStatus"));
+        columns.add(new ActionColumn<ReportTO, String>(new 
ResourceModel("actions", "")) {
+
+            private static final long serialVersionUID = 2054811145491901166L;
+
+            @Override
+            public ActionLinksPanel getActions(final String componentId, final 
IModel<ReportTO> model) {
+
+                final ReportTO reportTO = model.getObject();
+
+                final ActionLinksPanel panel = new 
ActionLinksPanel(componentId, model, getPageReference());
+
+                panel.add(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 ReportModalPage(window, reportTO, 
Reports.this.getPageReference());
+                            }
+                        });
+
+                        window.show(target);
+                    }
+                }, ActionLink.ActionType.EDIT, "Reports");
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = 
-3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        try {
+                            reportRestClient.startExecution(reportTO.getKey());
+                            
getSession().info(getString(Constants.OPERATION_SUCCEEDED));
+                        } catch (SyncopeClientException scce) {
+                            error(scce.getMessage());
+                        }
+
+                        feedbackPanel.refresh(target);
+                        target.add(reportContainer);
+                    }
+                }, ActionLink.ActionType.EXECUTE, "Reports");
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = 
-3722207913631435501L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        try {
+                            reportRestClient.delete(reportTO.getKey());
+                            info(getString(Constants.OPERATION_SUCCEEDED));
+                        } catch (SyncopeClientException scce) {
+                            error(scce.getMessage());
+                        }
+                        target.add(reportContainer);
+                        feedbackPanel.refresh(target);
+                    }
+                }, ActionLink.ActionType.DELETE, "Reports");
+
+                return panel;
+            }
+
+            @Override
+            public Component getHeader(final String componentId) {
+                final ActionLinksPanel panel = new 
ActionLinksPanel(componentId, new Model(), getPageReference());
+
+                panel.add(new ActionLink() {
+
+                    private static final long serialVersionUID = 
-7978723352517770644L;
+
+                    @Override
+                    public void onClick(final AjaxRequestTarget target) {
+                        if (target != null) {
+                            target.add(reportContainer);
+                        }
+                    }
+                }, ActionLink.ActionType.RELOAD, TASKS, "list");
+
+                return panel;
+            }
+        });
+
+        final AjaxFallbackDefaultDataTable<ReportTO, String> reportTable =
+                new AjaxFallbackDefaultDataTable<>("reportTable", columns, new 
ReportProvider(), paginatorRows);
+
+        reportContainer.add(reportTable);
+        reportContainer.setOutputMarkupId(true);
+
+        add(reportContainer);
+
+        @SuppressWarnings("rawtypes")
+        Form paginatorForm = new Form("paginatorForm");
+
+        MetaDataRoleAuthorizationStrategy.authorize(paginatorForm, RENDER,
+                xmlRolesReader.getEntitlement("Reports", "list"));
+
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        final DropDownChoice rowsChooser = new DropDownChoice("rowsChooser", 
new PropertyModel(this, "paginatorRows"),
+                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_REPORT_PAGINATOR_ROWS,
+                        String.valueOf(paginatorRows));
+                reportTable.setItemsPerPage(paginatorRows);
+
+                target.add(reportContainer);
+            }
+        });
+
+        paginatorForm.add(rowsChooser);
+        add(paginatorForm);
+
+        AjaxLink<Void> createLink = new 
ClearIndicatingAjaxLink<Void>("createLink", getPageReference()) {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            protected void onClickInternal(final AjaxRequestTarget target) {
+                window.setPageCreator(new ModalWindow.PageCreator() {
+
+                    private static final long serialVersionUID = 
-7834632442532690940L;
+
+                    @Override
+                    public Page createPage() {
+                        return new ReportModalPage(window, new ReportTO(), 
Reports.this.getPageReference());
+                    }
+                });
+
+                window.show(target);
+            }
+        };
+
+        MetaDataRoleAuthorizationStrategy.authorize(createLink, RENDER, 
xmlRolesReader.getEntitlement("Reports",
+                "create"));
+
+        add(createLink);
+    }
+
+    @SuppressWarnings("rawtypes")
+    private void setupAudit() {
+        auditContainer = new WebMarkupContainer("auditContainer");
+        auditContainer.setOutputMarkupId(true);
+        add(auditContainer);
+
+        MetaDataRoleAuthorizationStrategy.authorize(
+                auditContainer, RENDER, xmlRolesReader.getEntitlement("Audit", 
"list"));
+
+        final Form form = new Form("auditForm");
+        auditContainer.add(form);
+
+        final List<String> events = new ArrayList<>();
+
+        final List<AuditLoggerName> audits = loggerRestClient.listAudits();
+        for (AuditLoggerName audit : audits) {
+            events.add(AuditLoggerName.buildEvent(
+                    audit.getType(),
+                    audit.getCategory(),
+                    audit.getSubcategory(),
+                    audit.getEvent(),
+                    audit.getResult()));
+        }
+
+        final ListModel<String> model = new ListModel<>(new 
ArrayList<>(events));
+
+        form.add(new LoggerCategoryPanel(
+                "events", loggerRestClient.listEvents(), model, 
getPageReference(), "Reports") {
+
+                    private static final long serialVersionUID = 
6113164334533550277L;
+
+                    @Override
+                    protected String[] getListRoles() {
+                        return new String[] {
+                            xmlRolesReader.getEntitlement("Audit", "list")
+                        };
+                    }
+
+                    @Override
+                    protected String[] getChangeRoles() {
+                        return new String[] {
+                            xmlRolesReader.getEntitlement("Audit", "enable"),
+                            xmlRolesReader.getEntitlement("Audit", "disable")
+                        };
+                    }
+
+                    @Override
+                    public void onEventAction(final IEvent<?> event) {
+                        if (event.getPayload() instanceof 
SelectedEventsPanel.EventSelectionChanged) {
+
+                            final SelectedEventsPanel.EventSelectionChanged 
eventSelectionChanged =
+                            (SelectedEventsPanel.EventSelectionChanged) 
event.getPayload();
+
+                            for (String toBeRemoved : 
eventSelectionChanged.getToBeRemoved()) {
+                                if (events.contains(toBeRemoved)) {
+                                    Pair<EventCategoryTO, Result> 
eventCategory =
+                                    
AuditLoggerName.parseEventCategory(toBeRemoved);
+
+                                    final AuditLoggerName auditLoggerName = 
new AuditLoggerName(
+                                            eventCategory.getKey().getType(),
+                                            
eventCategory.getKey().getCategory(),
+                                            
eventCategory.getKey().getSubcategory(),
+                                            
CollectionUtils.isEmpty(eventCategory.getKey().getEvents())
+                                                    ? null : 
eventCategory.getKey().getEvents().iterator().next(),
+                                            eventCategory.getValue());
+
+                                    
loggerRestClient.disableAudit(auditLoggerName);
+                                    events.remove(toBeRemoved);
+                                }
+                            }
+
+                            for (String toBeAdded : 
eventSelectionChanged.getToBeAdded()) {
+                                if (!events.contains(toBeAdded)) {
+                                    Pair<EventCategoryTO, Result> 
eventCategory =
+                                    
AuditLoggerName.parseEventCategory(toBeAdded);
+
+                                    final AuditLoggerName auditLoggerName = 
new AuditLoggerName(
+                                            eventCategory.getKey().getType(),
+                                            
eventCategory.getKey().getCategory(),
+                                            
eventCategory.getKey().getSubcategory(),
+                                            
CollectionUtils.isEmpty(eventCategory.getKey().getEvents())
+                                                    ? null : 
eventCategory.getKey().getEvents().iterator().next(),
+                                            eventCategory.getValue());
+
+                                    
loggerRestClient.enableAudit(auditLoggerName);
+                                    events.add(toBeAdded);
+                                }
+                            }
+                        }
+                    }
+                });
+    }
+
+    private class ReportProvider extends SortableDataProvider<ReportTO, 
String> {
+
+        private static final long serialVersionUID = -2311716167583335852L;
+
+        private final SortableDataProviderComparator<ReportTO> comparator;
+
+        public ReportProvider() {
+            super();
+
+            //Default sorting
+            setSort("key", SortOrder.ASCENDING);
+            comparator = new SortableDataProviderComparator<>(this);
+        }
+
+        @Override
+        public Iterator<ReportTO> iterator(final long first, final long count) 
{
+            final int page = ((int) first / paginatorRows);
+
+            final List<ReportTO> list =
+                    reportRestClient.list((page < 0 ? 0 : page) + 1, 
paginatorRows, getSort());
+            Collections.sort(list, comparator);
+            return list.iterator();
+        }
+
+        @Override
+        public long size() {
+            return reportRestClient.count();
+        }
+
+        @Override
+        public IModel<ReportTO> model(final ReportTO configuration) {
+
+            return new AbstractReadOnlyModel<ReportTO>() {
+
+                private static final long serialVersionUID = 
4921104837546595602L;
+
+                @Override
+                public ReportTO getObject() {
+                    return configuration;
+                }
+            };
+        }
+    }
+}

Reply via email to