You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/02/16 09:07:06 UTC
[41/59] [abbrv] [partial] syncope git commit: [SYNCOPE-620]
Re-organization completed
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/pages/ReportModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ReportModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ReportModalPage.java
new file mode 100644
index 0000000..0ef7c6a
--- /dev/null
+++ b/client/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/2d194636/client/console/src/main/java/org/apache/syncope/client/console/pages/ReportletConfModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ReportletConfModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ReportletConfModalPage.java
new file mode 100644
index 0000000..e7155ca
--- /dev/null
+++ b/client/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.RoleSearchPanel;
+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.roleSearch()) {
+ panel = new RoleSearchPanel.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 RolePlainSchema:
+ choices = schemaRestClient.getPlainSchemaNames(AttributableType.ROLE);
+ break;
+
+ case RoleDerivedSchema:
+ choices = schemaRestClient.getDerSchemaNames(AttributableType.ROLE);
+ break;
+
+ case RoleVirtualSchema:
+ choices = schemaRestClient.getVirSchemaNames(AttributableType.ROLE);
+ 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/2d194636/client/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Reports.java
new file mode 100644
index 0000000..a7b9c6c
--- /dev/null
+++ b/client/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 java.util.Map;
+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)) {
+ final Map.Entry<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)) {
+ final Map.Entry<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;
+ }
+ };
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/pages/RequestPasswordResetModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/RequestPasswordResetModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/RequestPasswordResetModalPage.java
new file mode 100644
index 0000000..d8b762f
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/RequestPasswordResetModalPage.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.pages;
+
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.Mode;
+import org.apache.syncope.client.console.rest.SecurityQuestionRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.common.lib.to.SecurityQuestionTO;
+import org.apache.syncope.common.lib.to.UserTO;
+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.IndicatingAjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.StatelessForm;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public class RequestPasswordResetModalPage extends BaseModalPage {
+
+ private static final long serialVersionUID = -8419445804421211904L;
+
+ @SpringBean
+ private SecurityQuestionRestClient securityQuestionRestClient;
+
+ public RequestPasswordResetModalPage(final ModalWindow window) {
+ super();
+ setOutputMarkupId(true);
+
+ final boolean handleSecurityQuestion = userSelfRestClient.isPwdResetRequiringSecurityQuestions();
+
+ final StatelessForm<?> form = new StatelessForm<Object>(FORM);
+ form.setOutputMarkupId(true);
+
+ final Label securityQuestionLabel = new Label("securityQuestionLabel", getString("securityQuestion"));
+ securityQuestionLabel.setOutputMarkupPlaceholderTag(true);
+ securityQuestionLabel.setVisible(handleSecurityQuestion);
+ form.add(securityQuestionLabel);
+ final AjaxTextFieldPanel securityQuestion =
+ new AjaxTextFieldPanel("securityQuestion", "securityQuestion", new Model<String>());
+ securityQuestion.setReadOnly(true);
+ securityQuestion.setRequired(true);
+ securityQuestion.getField().setOutputMarkupId(true);
+ securityQuestion.setOutputMarkupPlaceholderTag(true);
+ securityQuestion.setVisible(handleSecurityQuestion);
+ form.add(securityQuestion);
+
+ final AjaxTextFieldPanel username =
+ new AjaxTextFieldPanel("username", "username", new Model<String>());
+ username.setRequired(true);
+ username.getField().setOutputMarkupId(true);
+ if (handleSecurityQuestion) {
+ username.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ getFeedbackMessages().clear();
+ target.add(feedbackPanel);
+ try {
+ SecurityQuestionTO read = securityQuestionRestClient.readByUser(username.getModelObject());
+ securityQuestion.setModelObject(read.getContent());
+ } catch (Exception e) {
+ LOG.error("While fetching security question for {}", username.getModelObject(), e);
+ error(getString(Constants.ERROR) + ": " + e.getMessage());
+ feedbackPanel.refresh(target);
+ securityQuestion.setModelObject(null);
+ } finally {
+ target.add(securityQuestion);
+ }
+ }
+ });
+ }
+ form.add(username);
+
+ final Label securityAnswerLabel = new Label("securityAnswerLabel", getString("securityAnswer"));
+ securityAnswerLabel.setOutputMarkupPlaceholderTag(true);
+ securityAnswerLabel.setVisible(handleSecurityQuestion);
+ form.add(securityAnswerLabel);
+ final AjaxTextFieldPanel securityAnswer =
+ new AjaxTextFieldPanel("securityAnswer", "securityAnswer", new Model<String>());
+ securityAnswer.setRequired(handleSecurityQuestion);
+ securityAnswer.setOutputMarkupPlaceholderTag(true);
+ securityAnswer.setVisible(handleSecurityQuestion);
+ form.add(securityAnswer);
+
+ final AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT, SUBMIT)) {
+
+ private static final long serialVersionUID = -4804368561204623354L;
+
+ @Override
+ protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+ try {
+ userSelfRestClient.requestPasswordReset(username.getModelObject(), securityAnswer.getModelObject());
+
+ setResponsePage(new ResultStatusModalPage.Builder(window, new UserTO()).
+ mode(Mode.SELF).build());
+ } catch (Exception e) {
+ LOG.error("While requesting password reset for {}", username.getModelObject(), e);
+ error(getString(Constants.ERROR) + ": " + e.getMessage());
+ feedbackPanel.refresh(target);
+ }
+ }
+
+ @Override
+ protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+ feedbackPanel.refresh(target);
+ }
+ };
+ form.add(submit);
+ form.setDefaultButton(submit);
+
+ final AjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) {
+
+ private static final long serialVersionUID = -958724007591692537L;
+
+ @Override
+ protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+ window.close(target);
+ }
+
+ @Override
+ protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+ // do nothing
+ }
+ };
+ cancel.setDefaultFormProcessing(false);
+ form.add(cancel);
+
+ add(form);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
new file mode 100644
index 0000000..d6f69cf
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
@@ -0,0 +1,214 @@
+/*
+ * 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.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.AnnotatedBeanPanel;
+import org.apache.syncope.client.console.panels.ResourceConnConfPanel;
+import org.apache.syncope.client.console.panels.ResourceDetailsPanel;
+import org.apache.syncope.client.console.panels.ResourceMappingPanel;
+import org.apache.syncope.client.console.panels.ResourceSecurityPanel;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+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.IndicatingAjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+
+/**
+ * Modal window with Resource form.
+ */
+public class ResourceModalPage extends BaseModalPage {
+
+ private static final long serialVersionUID = 1734415311027284221L;
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public ResourceModalPage(final PageReference pageRef, final ModalWindow window, final ResourceTO resourceTO,
+ final boolean createFlag) {
+
+ super();
+
+ this.add(new Label("new", StringUtils.isBlank(resourceTO.getKey())
+ ? new ResourceModel("new")
+ : new Model(StringUtils.EMPTY)));
+ this.add(new Label("name", StringUtils.isBlank(resourceTO.getKey())
+ ? StringUtils.EMPTY
+ : resourceTO.getKey()));
+
+ final Form<ResourceTO> form = new Form<>(FORM);
+ form.setModel(new CompoundPropertyModel<>(resourceTO));
+
+ //--------------------------------
+ // Resource details panel
+ //--------------------------------
+ form.add(new ResourceDetailsPanel("details", resourceTO,
+ resourceRestClient.getPropagationActionsClasses(), createFlag));
+
+ form.add(new AnnotatedBeanPanel("systeminformation", resourceTO));
+ //--------------------------------
+
+ //--------------------------------
+ // Resource mapping panels
+ //--------------------------------
+ form.add(new ResourceMappingPanel("umapping", resourceTO, AttributableType.USER));
+ form.add(new ResourceMappingPanel("rmapping", resourceTO, AttributableType.ROLE));
+ //--------------------------------
+
+ //--------------------------------
+ // Resource connector configuration panel
+ //--------------------------------
+ ResourceConnConfPanel resourceConnConfPanel = new ResourceConnConfPanel("connconf", resourceTO, createFlag);
+ MetaDataRoleAuthorizationStrategy.authorize(
+ resourceConnConfPanel, ENABLE, xmlRolesReader.getEntitlement("Connectors", "read"));
+ form.add(resourceConnConfPanel);
+ //--------------------------------
+
+ //--------------------------------
+ // Resource security panel
+ //--------------------------------
+ form.add(new ResourceSecurityPanel("security", resourceTO));
+ //--------------------------------
+
+ final AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT, SUBMIT)) {
+
+ private static final long serialVersionUID = -958724007591692537L;
+
+ @Override
+ protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+ final ResourceTO resourceTO = (ResourceTO) form.getDefaultModelObject();
+
+ boolean accountIdError = false;
+
+ if (resourceTO.getUmapping() == null || resourceTO.getUmapping().getItems().isEmpty()) {
+ resourceTO.setUmapping(null);
+ } else {
+ int uAccountIdCount = 0;
+ for (MappingItemTO item : resourceTO.getUmapping().getItems()) {
+ if (item.isAccountid()) {
+ uAccountIdCount++;
+ }
+ }
+ accountIdError = uAccountIdCount != 1;
+ }
+
+ if (resourceTO.getRmapping() == null || resourceTO.getRmapping().getItems().isEmpty()) {
+ resourceTO.setRmapping(null);
+ } else {
+ int rAccountIdCount = 0;
+ for (MappingItemTO item : resourceTO.getRmapping().getItems()) {
+ if (item.isAccountid()) {
+ rAccountIdCount++;
+ }
+ }
+ accountIdError |= rAccountIdCount != 1;
+ }
+
+ if (accountIdError) {
+ error(getString("accountIdValidation"));
+ feedbackPanel.refresh(target);
+ } else {
+ try {
+ if (createFlag) {
+ resourceRestClient.create(resourceTO);
+ } else {
+ resourceRestClient.update(resourceTO);
+ }
+
+ if (pageRef != null && pageRef.getPage() instanceof AbstractBasePage) {
+ ((AbstractBasePage) pageRef.getPage()).setModalResult(true);
+ }
+ window.close(target);
+ } catch (Exception e) {
+ LOG.error("Failure managing resource {}", resourceTO, e);
+ error(getString(Constants.ERROR) + ": " + e.getMessage());
+ feedbackPanel.refresh(target);
+ }
+ }
+ }
+
+ @Override
+ protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+ feedbackPanel.refresh(target);
+ }
+ };
+
+ form.add(submit);
+ form.setDefaultButton(submit);
+
+ final AjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) {
+
+ private static final long serialVersionUID = -958724007591692537L;
+
+ @Override
+ protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+ window.close(target);
+ }
+
+ @Override
+ protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+ }
+ };
+
+ cancel.setDefaultFormProcessing(false);
+ form.add(cancel);
+
+ add(form);
+
+ MetaDataRoleAuthorizationStrategy.authorize(
+ submit, ENABLE, xmlRolesReader.getEntitlement("Resources", createFlag ? "create" : "update"));
+ }
+
+ /**
+ * Generic resource event.
+ */
+ public static class ResourceEvent {
+
+ /**
+ * Request target.
+ */
+ private final AjaxRequestTarget target;
+
+ /**
+ * Constructor.
+ *
+ * @param target request target.
+ */
+ public ResourceEvent(final AjaxRequestTarget target) {
+ this.target = target;
+ }
+
+ /**
+ * Target getter.
+ *
+ * @return request target.
+ */
+ public AjaxRequestTarget getTarget() {
+ return target;
+ }
+ }
+}