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:02 UTC
[37/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/panels/AbstractSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
new file mode 100644
index 0000000..6139ee4
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
@@ -0,0 +1,353 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.syncope.client.console.commons.AttributableDataProvider;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.PreferenceManager;
+import org.apache.syncope.client.console.commons.XMLRolesReader;
+import org.apache.syncope.client.console.pages.AbstractBasePage;
+import org.apache.syncope.client.console.rest.AbstractSubjectRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.event.IEventSource;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractSearchResultPanel extends Panel implements IEventSource {
+
+ private static final long serialVersionUID = -9170191461250434024L;
+
+ /**
+ * Logger.
+ */
+ protected static final Logger LOG = LoggerFactory.getLogger(AbstractSearchResultPanel.class);
+
+ /**
+ * Edit modal window height.
+ */
+ private final static int EDIT_MODAL_WIN_HEIGHT = 550;
+
+ /**
+ * Edit modal window width.
+ */
+ private final static int EDIT_MODAL_WIN_WIDTH = 800;
+
+ /**
+ * Schemas to be shown modal window height.
+ */
+ private final static int DISPLAYATTRS_MODAL_WIN_HEIGHT = 550;
+
+ /**
+ * Schemas to be shown modal window width.
+ */
+ private final static int DISPLAYATTRS_MODAL_WIN_WIDTH = 550;
+
+ /**
+ * Schemas to be shown modal window height.
+ */
+ private final static int STATUS_MODAL_WIN_HEIGHT = 500;
+
+ /**
+ * Schemas to be shown modal window width.
+ */
+ private final static int STATUS_MODAL_WIN_WIDTH = 700;
+
+ /**
+ * Application preferences.
+ */
+ @SpringBean
+ protected PreferenceManager prefMan;
+
+ /**
+ * Role reader for authorizations management.
+ */
+ @SpringBean
+ protected XMLRolesReader xmlRolesReader;
+
+ protected final AbstractSubjectRestClient restClient;
+
+ /**
+ * Number of rows per page.
+ */
+ private final int rows;
+
+ /**
+ * Container used to refresh table.
+ */
+ protected final WebMarkupContainer container;
+
+ /**
+ * Feedback panel specified by the caller.
+ */
+ protected final NotificationPanel feedbackPanel;
+
+ /**
+ * Specify if results are about a filtered search or not. Using this attribute it is possible to use this panel to
+ * show results about user list and user search.
+ */
+ private final boolean filtered;
+
+ /**
+ * Filter used in case of filtered search.
+ */
+ private String fiql;
+
+ /**
+ * Result table.
+ */
+ private AjaxDataTablePanel<AbstractAttributableTO, String> resultTable;
+
+ /**
+ * Data provider used to search for users.
+ */
+ private AttributableDataProvider dataProvider;
+
+ /**
+ * Modal window to be used for user profile editing. Global visibility is required ...
+ */
+ protected final ModalWindow editmodal = new ModalWindow("editModal");
+
+ /**
+ * Modal window to be used for attributes choosing to display in tables.
+ */
+ protected final ModalWindow displaymodal = new ModalWindow("displayModal");
+
+ /**
+ * Modal window to be used for user status management.
+ */
+ protected final ModalWindow statusmodal = new ModalWindow("statusModal");
+
+ /**
+ * Owner page.
+ */
+ protected final AbstractBasePage page;
+
+ protected <T extends AbstractAttributableTO> AbstractSearchResultPanel(final String id, final boolean filtered,
+ final String fiql, final PageReference pageRef, final AbstractSubjectRestClient restClient) {
+
+ super(id);
+
+ setOutputMarkupId(true);
+
+ this.page = (AbstractBasePage) pageRef.getPage();
+
+ this.filtered = filtered;
+ this.fiql = fiql;
+ this.feedbackPanel = page.getFeedbackPanel();
+
+ this.restClient = restClient;
+
+ editmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+ editmodal.setInitialHeight(EDIT_MODAL_WIN_HEIGHT);
+ editmodal.setInitialWidth(EDIT_MODAL_WIN_WIDTH);
+ editmodal.setCookieName("edit-modal");
+ add(editmodal);
+
+ displaymodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+ displaymodal.setInitialHeight(DISPLAYATTRS_MODAL_WIN_HEIGHT);
+ displaymodal.setInitialWidth(DISPLAYATTRS_MODAL_WIN_WIDTH);
+ displaymodal.setCookieName("display-modal");
+ add(displaymodal);
+
+ statusmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+ statusmodal.setInitialHeight(STATUS_MODAL_WIN_HEIGHT);
+ statusmodal.setInitialWidth(STATUS_MODAL_WIN_WIDTH);
+ statusmodal.setCookieName("status-modal");
+ add(statusmodal);
+
+ // Container for user search result
+ container = new WebMarkupContainer("container");
+ container.setOutputMarkupId(true);
+ add(container);
+
+ rows = prefMan.getPaginatorRows(getRequest(), Constants.PREF_USERS_PAGINATOR_ROWS);
+ }
+
+ protected void initResultTable() {
+ // ---------------------------
+ // Result table initialization
+ // ---------------------------
+ updateResultTable(false);
+ // ---------------------------
+
+ // ---------------------------
+ // Rows-per-page selector
+ // ---------------------------
+ final Form<?> paginatorForm = new Form<>("paginator");
+ container.add(paginatorForm);
+
+ final DropDownChoice<Integer> rowsChooser = new DropDownChoice<>(
+ "rowsChooser", new PropertyModel<Integer>(this, "rows"), prefMan.getPaginatorChoices());
+
+ rowsChooser.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ prefMan.set(getRequest(), getResponse(), Constants.PREF_USERS_PAGINATOR_ROWS, String.valueOf(rows));
+
+ final EventDataWrapper data = new EventDataWrapper();
+ data.setTarget(target);
+ data.setRows(rows);
+
+ send(getParent(), Broadcast.BREADTH, data);
+ }
+ });
+ paginatorForm.add(rowsChooser);
+ // ---------------------------
+
+ setWindowClosedReloadCallback(statusmodal);
+ setWindowClosedReloadCallback(editmodal);
+ setWindowClosedReloadCallback(displaymodal);
+ }
+
+ public void search(final String fiql, final AjaxRequestTarget target) {
+ this.fiql = fiql;
+ dataProvider.setFIQL(fiql);
+ target.add(container);
+ }
+
+ private void updateResultTable(final boolean create) {
+ updateResultTable(create, rows);
+ }
+
+ private void updateResultTable(final boolean create, final int rows) {
+ dataProvider = new AttributableDataProvider(restClient, rows, filtered);
+ dataProvider.setFIQL(fiql);
+
+ final int currentPage = resultTable != null
+ ? (create
+ ? (int) resultTable.getPageCount() - 1
+ : (int) resultTable.getCurrentPage())
+ : 0;
+
+ resultTable = new AjaxDataTablePanel<>(
+ "resultTable",
+ getColumns(),
+ dataProvider,
+ rows,
+ getBulkActions(),
+ restClient,
+ "key",
+ getPageId(),
+ page.getPageReference());
+
+ resultTable.setCurrentPage(currentPage);
+
+ resultTable.setOutputMarkupId(true);
+
+ container.addOrReplace(resultTable);
+ }
+
+ protected abstract List<IColumn<AbstractAttributableTO, String>> getColumns();
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ if (event.getPayload() instanceof EventDataWrapper) {
+ final EventDataWrapper data = (EventDataWrapper) event.getPayload();
+
+ if (data.getRows() < 1) {
+ updateResultTable(data.isCreate());
+ } else {
+ updateResultTable(data.isCreate(), data.getRows());
+ }
+
+ data.getTarget().add(container);
+ }
+ }
+
+ private void setWindowClosedReloadCallback(final ModalWindow window) {
+ window.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+ private static final long serialVersionUID = 8804221891699487139L;
+
+ @Override
+ public void onClose(final AjaxRequestTarget target) {
+ final EventDataWrapper data = new EventDataWrapper();
+ data.setTarget(target);
+ data.setRows(rows);
+
+ send(getParent(), Broadcast.BREADTH, data);
+
+ if (page.isModalResult()) {
+ // reset modal result
+ page.setModalResult(false);
+ // set operation succeeded
+ getSession().info(getString(Constants.OPERATION_SUCCEEDED));
+ // refresh feedback panel
+ feedbackPanel.refresh(target);
+ }
+ }
+ });
+ }
+
+ public static class EventDataWrapper {
+
+ private AjaxRequestTarget target;
+
+ private boolean create;
+
+ private int rows;
+
+ public AjaxRequestTarget getTarget() {
+ return target;
+ }
+
+ public void setTarget(final AjaxRequestTarget target) {
+ this.target = target;
+ }
+
+ public boolean isCreate() {
+ return create;
+ }
+
+ public void setCreate(boolean create) {
+ this.create = create;
+ }
+
+ public int getRows() {
+ return rows;
+ }
+
+ public void setRows(int rows) {
+ this.rows = rows;
+ }
+ }
+
+ protected abstract <T extends AbstractAttributableTO> Collection<ActionLink.ActionType> getBulkActions();
+
+ protected abstract String getPageId();
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractTasks.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractTasks.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractTasks.java
new file mode 100644
index 0000000..381f878
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractTasks.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import org.apache.syncope.client.console.commons.PreferenceManager;
+import org.apache.syncope.client.console.commons.XMLRolesReader;
+import org.apache.syncope.client.console.rest.TaskRestClient;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public abstract class AbstractTasks extends Panel {
+
+ private static final long serialVersionUID = -1190836516156843561L;
+
+ protected static final String VIEW_TASK_WIN_COOKIE_NAME = "view-task-win";
+
+ protected static final int WIN_HEIGHT = 500;
+
+ protected static final int WIN_WIDTH = 700;
+
+ protected static final String TASKS = "Tasks";
+
+ protected PageReference pageRef;
+
+ @SpringBean
+ protected TaskRestClient restClient;
+
+ @SpringBean
+ protected PreferenceManager prefMan;
+
+ @SpringBean
+ protected XMLRolesReader xmlRolesReader;
+
+ public AbstractTasks(final String id, final PageReference pageRef) {
+ super(id);
+ this.pageRef = pageRef;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountInformationPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountInformationPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountInformationPanel.java
new file mode 100644
index 0000000..3bc7dd8
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountInformationPanel.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeSession;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.model.Model;
+
+public class AccountInformationPanel extends AnnotatedBeanPanel {
+
+ private static final long serialVersionUID = 4228064224811390808L;
+
+ public <T extends AbstractAttributableTO> AccountInformationPanel(final String id, final UserTO userTO) {
+ super(id, userTO);
+
+ // ------------------------
+ // Change password date
+ // ------------------------
+ add(new Label("changePwdDate", new Model<String>(userTO.getChangePwdDate() == null
+ ? StringUtils.EMPTY
+ : SyncopeSession.get().getDateFormat().format(userTO.getChangePwdDate()))));
+ // ------------------------
+
+ // ------------------------
+ // Last login date
+ // ------------------------
+ add(new Label("lastLoginDate", new Model<String>(userTO.getLastLoginDate() == null
+ ? StringUtils.EMPTY
+ : SyncopeSession.get().getDateFormat().format(userTO.getLastLoginDate()))));
+ // ------------------------
+
+ // ------------------------
+ // Failed logins
+ // ------------------------
+ add(new Label("failedLogins", new Model<Integer>(userTO.getFailedLogins())));
+ // ------------------------
+
+ // ------------------------
+ // Token
+ // ------------------------
+ add(new Label("token", new Model<String>(userTO.getToken() == null
+ ? StringUtils.EMPTY
+ : userTO.getToken())));
+ // ------------------------
+
+ // ------------------------
+ // Token expire time
+ // ------------------------
+ add(new Label("tokenExpireTime", new Model<String>(userTO.getTokenExpireTime() == null
+ ? StringUtils.EMPTY
+ : SyncopeSession.get().getDateFormat().format(userTO.getTokenExpireTime()))));
+ // ------------------------
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
new file mode 100644
index 0000000..bfade98
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.syncope.client.console.commons.ActionTableCheckGroup;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CheckGroupColumn;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+
+public class ActionDataTablePanel<T, S> extends DataTablePanel<T, S> {
+
+ private static final long serialVersionUID = -8826989026203543957L;
+
+ private static final String CANCEL = "cancel";
+
+ private final Form<T> bulkActionForm;
+
+ private final ActionLinksPanel actionPanel;
+
+ private final PageReference pageRef;
+
+ public ActionDataTablePanel(
+ final String id,
+ final List<IColumn<T, S>> columns,
+ final ISortableDataProvider<T, S> dataProvider,
+ final int rowsPerPage,
+ final PageReference pageRef) {
+
+ super(id);
+
+ this.pageRef = pageRef;
+
+ bulkActionForm = new Form<T>("groupForm");
+ add(bulkActionForm);
+
+ group = new ActionTableCheckGroup<T>("checkgroup", model) {
+
+ private static final long serialVersionUID = -8667764190925075389L;
+
+ @Override
+ public boolean isCheckable(final T element) {
+ return isElementEnabled(element);
+ }
+ };
+ group.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+ private static final long serialVersionUID = -151291731388673682L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ // triggers AJAX form submit
+ }
+ });
+ bulkActionForm.add(group);
+
+ columns.add(0, new CheckGroupColumn<T, S>(group));
+ dataTable = new AjaxFallbackDefaultDataTable<T, S>("dataTable", columns, dataProvider, rowsPerPage);
+ group.add(dataTable);
+
+ final WebMarkupContainer actionPanelContainer = new WebMarkupContainer("actionPanelContainer");
+ bulkActionForm.add(actionPanelContainer);
+
+ actionPanel = new ActionLinksPanel("actions", new Model(), pageRef);
+ actionPanelContainer.add(actionPanel);
+
+ if (dataTable.getRowCount() == 0) {
+ actionPanelContainer.add(new AttributeModifier("style", "display: none"));
+ }
+
+ bulkActionForm.add(new ClearIndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL), pageRef) {
+
+ private static final long serialVersionUID = -2341391430136818025L;
+
+ @Override
+ protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) {
+ // ignore
+ }
+ }.setVisible(false).setEnabled(false));
+ }
+
+ public void addAction(final ActionLink action, final ActionType type, final String pageId) {
+ actionPanel.add(action, type, pageId);
+ }
+
+ public void addAction(final ActionLink action, final ActionType type, final String pageId, final String actionId) {
+ actionPanel.add(action, type, pageId, actionId);
+ }
+
+ public void addAction(final ActionLink action, final ActionType type, final String pageId, final boolean enabled) {
+ actionPanel.add(action, type, pageId, enabled);
+ }
+
+ public void addCancelButton(final ModalWindow window) {
+
+ final AjaxButton cancel = new ClearIndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL), pageRef) {
+
+ private static final long serialVersionUID = -2341391430136818025L;
+
+ @Override
+ protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) {
+ window.close(target);
+ }
+ }.feedbackPanelAutomaticReload(false);
+
+ cancel.setDefaultFormProcessing(false);
+ bulkActionForm.addOrReplace(cancel);
+ }
+
+ public Collection<T> getModelObject() {
+ return group.getModelObject();
+ }
+
+ public boolean isElementEnabled(final T element) {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
new file mode 100644
index 0000000..563bd17
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.syncope.client.console.rest.BaseRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.panels.AbstractSearchResultPanel.EventDataWrapper;
+import org.apache.syncope.client.console.pages.AbstractBasePage;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CheckGroupColumn;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton;
+import org.apache.syncope.client.console.pages.BulkActionModalPage;
+import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Fragment;
+
+public class AjaxDataTablePanel<T, S> extends DataTablePanel<T, S> {
+
+ private static final long serialVersionUID = -7264400471578272966L;
+
+ public AjaxDataTablePanel(
+ final String id,
+ final List<IColumn<T, S>> columns,
+ final ISortableDataProvider<T, S> dataProvider,
+ final int rowsPerPage,
+ final Collection<ActionLink.ActionType> actions,
+ final BaseRestClient bulkActionExecutor,
+ final String itemIdField,
+ final String pageId,
+ final PageReference pageRef) {
+
+ super(id);
+
+ final ModalWindow bulkModalWin = new ModalWindow("bulkModal");
+ bulkModalWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+ bulkModalWin.setInitialHeight(600);
+ bulkModalWin.setInitialWidth(900);
+ bulkModalWin.setCookieName("bulk-modal");
+ add(bulkModalWin);
+
+ bulkModalWin.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+ private static final long serialVersionUID = 8804221891699487149L;
+
+ @Override
+ public void onClose(final AjaxRequestTarget target) {
+ final EventDataWrapper data = new EventDataWrapper();
+ data.setTarget(target);
+ data.setRows(rowsPerPage);
+
+ send(pageRef.getPage(), Broadcast.BREADTH, data);
+
+ final AbstractBasePage page = (AbstractBasePage) pageRef.getPage();
+
+ if (page.isModalResult()) {
+ // reset modal result
+ page.setModalResult(false);
+ // set operation succeeded
+ getSession().info(getString(Constants.OPERATION_SUCCEEDED));
+ // refresh feedback panel
+ target.add(page.getFeedbackPanel());
+ }
+ }
+ });
+
+ Fragment fragment = new Fragment("tablePanel", "bulkAvailable", this);
+ add(fragment);
+
+ Form<T> bulkActionForm = new Form<>("groupForm");
+ fragment.add(bulkActionForm);
+
+ group = new CheckGroup<>("checkgroup", model);
+ group.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+ private static final long serialVersionUID = -151291731388673682L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ // triggers AJAX form submit
+ }
+ });
+ bulkActionForm.add(group);
+
+ columns.add(0, new CheckGroupColumn<T, S>(group));
+ dataTable = new AjaxFallbackDefaultDataTable<>("dataTable", columns, dataProvider, rowsPerPage);
+ group.add(dataTable);
+
+ fragment.add(new ClearIndicatingAjaxButton("bulkActionLink", bulkActionForm, pageRef) {
+
+ private static final long serialVersionUID = 382302811235019988L;
+
+ @Override
+ protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) {
+ bulkModalWin.setPageCreator(new ModalWindow.PageCreator() {
+
+ private static final long serialVersionUID = -7834632442532690941L;
+
+ @Override
+ public Page createPage() {
+ return new BulkActionModalPage<>(
+ bulkModalWin,
+ group.getModelObject(),
+ columns,
+ actions,
+ bulkActionExecutor,
+ itemIdField,
+ pageId);
+ }
+ });
+
+ bulkModalWin.show(target);
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
new file mode 100644
index 0000000..714cb5f
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import org.apache.syncope.client.console.SyncopeSession;
+import org.apache.syncope.common.lib.to.AbstractAnnotatedBean;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+
+public class AnnotatedBeanPanel extends Panel {
+
+ private static final long serialVersionUID = 4228064224811390809L;
+
+ public <T extends AbstractAttributableTO> AnnotatedBeanPanel(
+ final String id, final AbstractAnnotatedBean sysInfoTO) {
+
+ super(id);
+
+ // ------------------------
+ // Creation date
+ // ------------------------
+ add(new Label("creationDate", new Model<String>(sysInfoTO.getCreationDate() != null
+ ? SyncopeSession.get().getDateFormat().format(sysInfoTO.getCreationDate()) : "")));
+ // ------------------------
+
+ // ------------------------
+ // Last change date
+ // ------------------------
+ add(new Label("lastChangeDate", new Model<String>(sysInfoTO.getLastChangeDate() != null
+ ? SyncopeSession.get().getDateFormat().format(sysInfoTO.getCreationDate()) : "")));
+ // ------------------------
+
+ // ------------------------
+ // Creator
+ // ------------------------
+ add(new Label("creator", new Model<String>(sysInfoTO.getCreator() != null
+ ? sysInfoTO.getCreator() : "")));
+ // ------------------------
+
+ // ------------------------
+ // Last modifier
+ // ------------------------
+ add(new Label("lastModifier", new Model<String>(sysInfoTO.getLastModifier() != null
+ ? sysInfoTO.getLastModifier() : "")));
+ // ------------------------
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/AttrTemplatesPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AttrTemplatesPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AttrTemplatesPanel.java
new file mode 100644
index 0000000..1601ca7
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AttrTemplatesPanel.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.SelectChoiceRenderer;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.NonI18nPalette;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.extensions.markup.html.form.palette.component.Recorder;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.util.ListModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public class AttrTemplatesPanel extends Panel {
+
+ public enum Type {
+
+ rPlainAttrTemplates,
+ rDerAttrTemplates,
+ rVirAttrTemplates,
+ mPlainAttrTemplates,
+ mDerAttrTemplates,
+ mVirAttrTemplates;
+
+ }
+
+ private static final long serialVersionUID = 1016028222120619000L;
+
+ @SpringBean
+ private SchemaRestClient schemaRestClient;
+
+ private final RoleTO roleTO;
+
+ private final NonI18nPalette<String> rPlainAttrTemplates;
+
+ private final NonI18nPalette<String> rDerAttrTemplates;
+
+ private final NonI18nPalette<String> rVirAttrTemplates;
+
+ public AttrTemplatesPanel(final String id, final RoleTO roleTO) {
+ super(id);
+ this.roleTO = roleTO;
+
+ rPlainAttrTemplates = buildPalette(Type.rPlainAttrTemplates,
+ schemaRestClient.getSchemaNames(AttributableType.ROLE, SchemaType.PLAIN));
+ this.add(rPlainAttrTemplates);
+ rDerAttrTemplates = buildPalette(Type.rDerAttrTemplates,
+ schemaRestClient.getSchemaNames(AttributableType.ROLE, SchemaType.DERIVED));
+ this.add(rDerAttrTemplates);
+ rVirAttrTemplates = buildPalette(Type.rVirAttrTemplates,
+ schemaRestClient.getSchemaNames(AttributableType.ROLE, SchemaType.VIRTUAL));
+ this.add(rVirAttrTemplates);
+
+ this.add(buildPalette(Type.mPlainAttrTemplates,
+ schemaRestClient.getSchemaNames(AttributableType.MEMBERSHIP, SchemaType.PLAIN)));
+ this.add(buildPalette(Type.mDerAttrTemplates,
+ schemaRestClient.getSchemaNames(AttributableType.MEMBERSHIP, SchemaType.DERIVED)));
+ this.add(buildPalette(Type.mVirAttrTemplates,
+ schemaRestClient.getSchemaNames(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL)));
+ }
+
+ private NonI18nPalette<String> buildPalette(final Type type, final List<String> allSchemas) {
+ if (allSchemas != null && !allSchemas.isEmpty()) {
+ Collections.sort(allSchemas);
+ }
+ ListModel<String> availableSchemas = new ListModel<>(allSchemas);
+
+ return new NonI18nPalette<String>(type.name(), new PropertyModel<List<String>>(roleTO, type.name()),
+ availableSchemas, new SelectChoiceRenderer<String>(), 8, false, true) {
+
+ private static final long serialVersionUID = 2295567122085510330L;
+
+ @Override
+ protected Recorder<String> newRecorderComponent() {
+ final Recorder<String> recorder = super.newRecorderComponent();
+
+ switch (type) {
+ case rPlainAttrTemplates:
+ case rDerAttrTemplates:
+ case rVirAttrTemplates:
+ recorder.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ send(getPage(), Broadcast.BREADTH, new RoleAttrTemplatesChange(type, target));
+ }
+ });
+ break;
+
+ default:
+ }
+
+ return recorder;
+ }
+ };
+ }
+
+ public Collection<String> getSelected(final Type type) {
+ Collection<String> selected;
+ switch (type) {
+ case rPlainAttrTemplates:
+ selected = this.rPlainAttrTemplates.getModelCollection();
+ break;
+
+ case rDerAttrTemplates:
+ selected = this.rDerAttrTemplates.getModelCollection();
+ break;
+
+ case rVirAttrTemplates:
+ selected = this.rVirAttrTemplates.getModelCollection();
+ break;
+
+ default:
+ selected = Collections.emptyList();
+ }
+
+ return selected;
+ }
+
+ public static class RoleAttrTemplatesChange {
+
+ private final Type type;
+
+ private final AjaxRequestTarget target;
+
+ public RoleAttrTemplatesChange(final Type type, final AjaxRequestTarget target) {
+ this.type = type;
+ this.target = target;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public AjaxRequestTarget getTarget() {
+ return target;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
new file mode 100644
index 0000000..a5f6588
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DataTablePanel.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import org.apache.wicket.Component;
+import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.DataGridView;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class DataTablePanel<T, S> extends Panel {
+
+ private static final long serialVersionUID = -7264400471578272966L;
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(DataTablePanel.class);
+
+ protected CheckGroup<T> group;
+
+ protected AjaxFallbackDefaultDataTable<T, S> dataTable;
+
+ protected IModel<Collection<T>> model;
+
+ public DataTablePanel(final String id) {
+ super(id);
+
+ model = new IModel<Collection<T>>() {
+
+ private static final long serialVersionUID = 4886729136344643465L;
+
+ private Collection<T> values = new HashSet<T>();
+
+ @Override
+ public Collection<T> getObject() {
+ // Someone or something call this method to change the model: this is not the right behavior.
+ // Return a copy of the model object in order to avoid SYNCOPE-465
+ return new HashSet<T>(values);
+ }
+
+ @Override
+ public void setObject(final Collection<T> selected) {
+ final Collection<T> all = getGroupModelObjects();
+ values.removeAll(all);
+ values.addAll(selected);
+ }
+
+ @Override
+ public void detach() {
+ }
+ };
+ }
+
+ public final void setCurrentPage(final long page) {
+ dataTable.setCurrentPage(page);
+ }
+
+ public final long getRowCount() {
+ return dataTable.getRowCount();
+ }
+
+ public final long getCurrentPage() {
+ return dataTable.getCurrentPage();
+ }
+
+ public final long getPageCount() {
+ return dataTable.getPageCount();
+ }
+
+ public void setItemsPerPage(final int resourcePaginatorRows) {
+ dataTable.setItemsPerPage(resourcePaginatorRows);
+ }
+
+ protected Collection<T> getGroupModelObjects() {
+ final Set<T> res = new HashSet<T>();
+
+ final Component rows = group.get("dataTable:body:rows");
+ if (rows instanceof DataGridView) {
+ @SuppressWarnings("unchecked")
+ final Iterator<Item<T>> iter = ((DataGridView<T>) rows).getItems();
+
+ while (iter.hasNext()) {
+ res.add(iter.next().getModelObject());
+ }
+ }
+ return res;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/DerAttrsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/DerAttrsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/DerAttrsPanel.java
new file mode 100644
index 0000000..d68038f
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/DerAttrsPanel.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.AttrTemplatesPanel.RoleAttrTemplatesChange;
+import org.apache.syncope.client.console.rest.RoleRestClient;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDecoratedCheckbox;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxCallListener;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.ajax.attributes.IAjaxCallListener;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public class DerAttrsPanel extends Panel {
+
+ private static final long serialVersionUID = -5387344116983102292L;
+
+ @SpringBean
+ private SchemaRestClient schemaRestClient;
+
+ @SpringBean
+ private RoleRestClient roleRestClient;
+
+ private final AttrTemplatesPanel attrTemplates;
+
+ public <T extends AbstractAttributableTO> DerAttrsPanel(final String id, final T entityTO) {
+ this(id, entityTO, null);
+ }
+
+ public <T extends AbstractAttributableTO> DerAttrsPanel(final String id, final T entityTO,
+ final AttrTemplatesPanel attrTemplates) {
+
+ super(id);
+ this.attrTemplates = attrTemplates;
+ setOutputMarkupId(true);
+
+ final IModel<List<String>> derSchemas = new LoadableDetachableModel<List<String>>() {
+
+ private static final long serialVersionUID = 5275935387613157437L;
+
+ @Override
+ protected List<String> load() {
+ List<String> derSchemaNames;
+
+ if (entityTO instanceof RoleTO) {
+ final RoleTO roleTO = (RoleTO) entityTO;
+
+ if (attrTemplates == null) {
+ derSchemaNames = roleTO.getRDerAttrTemplates();
+ } else {
+ derSchemaNames = new ArrayList<>(
+ attrTemplates.getSelected(AttrTemplatesPanel.Type.rDerAttrTemplates));
+ if (roleTO.isInheritTemplates() && roleTO.getParent() != 0) {
+ derSchemaNames.addAll(roleRestClient.read(roleTO.getParent()).getRDerAttrTemplates());
+ }
+ }
+ } else if (entityTO instanceof UserTO) {
+ derSchemaNames = schemaRestClient.getDerSchemaNames(AttributableType.USER);
+ } else {
+ derSchemaNames = roleRestClient.read(((MembershipTO) entityTO).getRoleId()).getMDerAttrTemplates();
+ }
+
+ return derSchemaNames;
+ }
+ };
+
+ final WebMarkupContainer attributesContainer = new WebMarkupContainer("derAttrContainer");
+
+ attributesContainer.setOutputMarkupId(true);
+ add(attributesContainer);
+
+ AjaxButton addAttributeBtn = new IndicatingAjaxButton("addAttributeBtn", new ResourceModel("addAttributeBtn")) {
+
+ private static final long serialVersionUID = -4804368561204623354L;
+
+ @Override
+ protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+ entityTO.getDerAttrs().add(new AttrTO());
+ target.add(attributesContainer);
+ }
+
+ @Override
+ protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+ target.add(attributesContainer);
+ }
+ };
+ add(addAttributeBtn.setDefaultFormProcessing(false));
+
+ ListView<AttrTO> attributes = new ListView<AttrTO>("attrs",
+ new PropertyModel<List<? extends AttrTO>>(entityTO, "derAttrs")) {
+
+ private static final long serialVersionUID = 9101744072914090143L;
+
+ @Override
+ protected void populateItem(final ListItem<AttrTO> item) {
+ final AttrTO attributeTO = item.getModelObject();
+
+ item.add(new AjaxDecoratedCheckbox("toRemove", new Model<>(Boolean.FALSE)) {
+
+ private static final long serialVersionUID = 7170946748485726506L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ entityTO.getDerAttrs().remove(attributeTO);
+ target.add(attributesContainer);
+ }
+
+ @Override
+ protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+ super.updateAjaxAttributes(attributes);
+
+ IAjaxCallListener ajaxCallListener = new AjaxCallListener() {
+
+ private static final long serialVersionUID = 7160235486520935153L;
+
+ @Override
+ public CharSequence getPrecondition(final Component component) {
+ return "if (!confirm('" + getString("confirmDelete") + "')) return false;";
+ }
+ };
+ attributes.getAjaxCallListeners().add(ajaxCallListener);
+ }
+ });
+
+ final DropDownChoice<String> schemaChoice = new DropDownChoice<String>("schema",
+ new PropertyModel<String>(attributeTO, "schema"), derSchemas);
+ schemaChoice.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ attributeTO.setSchema(schemaChoice.getModelObject());
+ }
+ });
+ schemaChoice.setRequired(true);
+ schemaChoice.setOutputMarkupId(true);
+ schemaChoice.setRequired(true);
+ item.add(schemaChoice);
+
+ final List<String> values = attributeTO.getValues();
+ if (values == null || values.isEmpty()) {
+ item.add(new TextField<String>("value",
+ new Model<String>(null)).setVisible(false));
+ } else {
+ item.add(new TextField<String>("value",
+ new Model<String>(values.get(0))).setEnabled(false));
+ }
+ }
+ };
+ attributesContainer.add(attributes);
+ }
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ if ((event.getPayload() instanceof RoleAttrTemplatesChange)) {
+ final RoleAttrTemplatesChange update = (RoleAttrTemplatesChange) event.getPayload();
+ if (attrTemplates != null && update.getType() == AttrTemplatesPanel.Type.rDerAttrTemplates) {
+ update.getTarget().add(this);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/EventSelectionPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/EventSelectionPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/EventSelectionPanel.java
new file mode 100644
index 0000000..5332cb5
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/EventSelectionPanel.java
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.wicket.markup.html.list.AltListView;
+import org.apache.syncope.common.lib.to.EventCategoryTO;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Check;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.form.CheckGroupSelector;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class EventSelectionPanel extends Panel {
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(EventSelectionPanel.class);
+
+ private static final long serialVersionUID = 752233163798301002L;
+
+ private final Set<String> selected = new HashSet<String>();
+
+ public EventSelectionPanel(
+ final String id, final EventCategoryTO eventCategoryTO, final IModel<List<String>> model) {
+ super(id);
+ setOutputMarkupId(true);
+
+ final List<String> events = getEvents(eventCategoryTO);
+
+ // needed to avoid model reset: model have to be managed into SelectedEventsPanel
+ selected.addAll(model.getObject());
+
+ final CheckGroup<String> successGroup = new CheckGroup<String>(
+ "successGroup",
+ selected);
+
+ successGroup.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+ private static final long serialVersionUID = -151291731388673682L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+
+ final Set<String> toBeRemoved = new HashSet<>();
+ final Set<String> toBeAdded = new HashSet<>();
+
+ for (String event : getEvents(eventCategoryTO)) {
+ final String eventString = AuditLoggerName.buildEvent(
+ eventCategoryTO.getType(),
+ eventCategoryTO.getCategory(),
+ eventCategoryTO.getSubcategory(),
+ event,
+ AuditElements.Result.SUCCESS);
+
+ if (successGroup.getModelObject().contains(eventString)) {
+ toBeAdded.add(eventString);
+ } else {
+ toBeRemoved.add(eventString);
+ }
+ }
+
+ send(EventSelectionPanel.this.getPage(), Broadcast.BREADTH,
+ new SelectedEventsPanel.EventSelectionChanged(target, toBeAdded, toBeRemoved));
+ }
+ });
+
+ successGroup.setVisible(!events.isEmpty());
+ add(successGroup);
+
+ add(new Label("successLabel", new ResourceModel("Success", "Success"))).setVisible(!events.isEmpty());
+
+ final CheckGroupSelector successSelector = new CheckGroupSelector("successSelector", successGroup);
+ successSelector.setVisible(!events.isEmpty());
+ add(successSelector);
+
+ final ListView<String> categoryView = new AltListView<String>("categoryView", events) {
+
+ private static final long serialVersionUID = 4949588177564901031L;
+
+ @Override
+ protected void populateItem(final ListItem<String> item) {
+ final String subcategory = item.getModelObject();
+
+ item.add(new Label("subcategory", new ResourceModel(subcategory, subcategory)));
+ }
+ };
+ add(categoryView);
+
+ final ListView<String> successView = new AltListView<String>("successView", events) {
+
+ private static final long serialVersionUID = 4949588177564901031L;
+
+ @Override
+ protected void populateItem(final ListItem<String> item) {
+ final String event = item.getModelObject();
+
+ final Check<String> successCheck = new Check<>("successCheck",
+ new Model<String>(AuditLoggerName.buildEvent(
+ eventCategoryTO.getType(),
+ eventCategoryTO.getCategory(),
+ eventCategoryTO.getSubcategory(),
+ event,
+ AuditElements.Result.SUCCESS)),
+ successGroup);
+ item.add(successCheck);
+ }
+ };
+ successGroup.add(successView);
+
+ final CheckGroup<String> failureGroup = new CheckGroup<String>(
+ "failureGroup",
+ selected);
+
+ failureGroup.add(new AjaxFormChoiceComponentUpdatingBehavior() {
+
+ private static final long serialVersionUID = -151291731388673682L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+
+ final Set<String> toBeRemoved = new HashSet<>();
+ final Set<String> toBeAdded = new HashSet<>();
+
+ for (String event : getEvents(eventCategoryTO)) {
+ final String eventString = AuditLoggerName.buildEvent(
+ eventCategoryTO.getType(),
+ eventCategoryTO.getCategory(),
+ eventCategoryTO.getSubcategory(),
+ event,
+ AuditElements.Result.FAILURE);
+
+ if (failureGroup.getModelObject().contains(eventString)) {
+ toBeAdded.add(eventString);
+ } else {
+ toBeRemoved.add(eventString);
+ }
+ }
+
+ send(EventSelectionPanel.this.getPage(), Broadcast.BREADTH,
+ new SelectedEventsPanel.EventSelectionChanged(target, toBeAdded, toBeRemoved));
+ }
+ });
+
+ failureGroup.setVisible(!events.isEmpty());
+ add(failureGroup);
+
+ add(new Label("failureLabel", new ResourceModel("Failure", "Failure"))).setVisible(!events.isEmpty());
+
+ final CheckGroupSelector failureSelector = new CheckGroupSelector("failureSelector", failureGroup);
+ failureSelector.setVisible(!events.isEmpty());
+ add(failureSelector);
+
+ final ListView<String> failureView = new AltListView<String>("failureView", events) {
+
+ private static final long serialVersionUID = 4949588177564901031L;
+
+ @Override
+ protected void populateItem(final ListItem<String> item) {
+ final String event = item.getModelObject();
+
+ final Check<String> failureCheck = new Check<>("failureCheck",
+ new Model<String>(AuditLoggerName.buildEvent(
+ eventCategoryTO.getType(),
+ eventCategoryTO.getCategory(),
+ eventCategoryTO.getSubcategory(),
+ event,
+ AuditElements.Result.FAILURE)),
+ failureGroup);
+ item.add(failureCheck);
+ }
+ };
+ failureGroup.add(failureView);
+ }
+
+ private List<String> getEvents(final EventCategoryTO eventCategoryTO) {
+ final List<String> res;
+
+ res = eventCategoryTO.getEvents();
+
+ if (res.isEmpty()) {
+ if ((AuditElements.EventCategoryType.PROPAGATION == eventCategoryTO.getType()
+ || AuditElements.EventCategoryType.SYNCHRONIZATION == eventCategoryTO.getType()
+ || AuditElements.EventCategoryType.PUSH == eventCategoryTO.getType())
+ && StringUtils.isEmpty(eventCategoryTO.getCategory())) {
+ res.add(eventCategoryTO.getType().toString());
+ } else if (AuditElements.EventCategoryType.TASK == eventCategoryTO.getType()
+ && StringUtils.isNotEmpty(eventCategoryTO.getCategory())) {
+ res.add(eventCategoryTO.getCategory());
+ }
+ } else {
+ Collections.sort(res);
+ }
+
+ return res;
+ }
+
+ /**
+ * To be extended in order to add actions on events.
+ *
+ * @param event event.
+ */
+ protected abstract void onEventAction(final IEvent<?> event);
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ onEventAction(event);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/ImagePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ImagePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ImagePanel.java
new file mode 100644
index 0000000..7969c63
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ImagePanel.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.html.image.Image;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.request.resource.ContextRelativeResource;
+
+public class ImagePanel extends Panel {
+
+ private static final long serialVersionUID = 5564818820574092960L;
+
+ final Image img;
+
+ public ImagePanel(final String id, final ContextRelativeResource img) {
+ super(id);
+ this.img = new Image("img", img);
+ add(this.img);
+ }
+
+ @Override
+ public Component add(final Behavior... behaviors) {
+ this.img.add(behaviors);
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/JQueryUITabbedPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/JQueryUITabbedPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/JQueryUITabbedPanel.java
new file mode 100644
index 0000000..d898ba6
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/JQueryUITabbedPanel.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.panels;
+
+import java.util.List;
+import org.apache.wicket.extensions.ajax.markup.html.tabs.AjaxTabbedPanel;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
+
+/**
+ * AjaxTabbedPanel with JQueryUI styling.
+ */
+public class JQueryUITabbedPanel<T extends ITab> extends AjaxTabbedPanel<T> {
+
+ private static final long serialVersionUID = -5059184710433341333L;
+
+ public JQueryUITabbedPanel(final String id, final List<T> tabs) {
+ super(id, tabs);
+ }
+
+ @Override
+ protected String getTabContainerCssClass() {
+ return "";
+ }
+
+ @Override
+ protected String getSelectedTabCssClass() {
+ return "ui-state-active selected";
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/LayoutsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/LayoutsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/LayoutsPanel.java
new file mode 100644
index 0000000..26f1894
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/LayoutsPanel.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.util.List;
+import org.apache.syncope.client.console.commons.AttrLayoutType;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.SelectChoiceRenderer;
+import org.apache.syncope.client.console.commons.XMLRolesReader;
+import org.apache.syncope.client.console.rest.ConfigurationRestClient;
+import org.apache.syncope.client.console.rest.SchemaRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.model.util.ListModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LayoutsPanel extends Panel {
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(LayoutsPanel.class);
+
+ private static final long serialVersionUID = -6804066913177804275L;
+
+ private static final String CANCEL = "cancel";
+
+ private static final String APPLY = "apply";
+
+ @SpringBean
+ protected XMLRolesReader xmlRolesReader;
+
+ @SpringBean
+ private SchemaRestClient schemaRestClient;
+
+ @SpringBean
+ private ConfigurationRestClient confRestClient;
+
+ @SuppressWarnings("unchecked")
+ public LayoutsPanel(final String id, final AttrLayoutType attrLayoutType, final NotificationPanel feedbackPanel) {
+ super(id);
+
+ final WebMarkupContainer container = new WebMarkupContainer("container");
+ container.setOutputMarkupId(true);
+
+ final Form<String> form = new Form<String>("form");
+ form.setOutputMarkupId(true);
+
+ final AttrTO attrLayout = confRestClient.readAttrLayout(attrLayoutType);
+ form.setModel(new CompoundPropertyModel(attrLayout.getValues()));
+
+ final List<String> fields = schemaRestClient.getPlainSchemaNames(attrLayoutType.getAttrType());
+ final ListModel<String> selectedFields =
+ new ListModel<String>(attrLayout.getValues().isEmpty() ? fields : attrLayout.getValues());
+ final ListModel<String> availableFields = new ListModel<String>(fields);
+
+ form.add(new AjaxPalettePanel<String>("fields", selectedFields, availableFields,
+ new SelectChoiceRenderer<String>(), true, true));
+
+ final AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(APPLY)) {
+
+ private static final long serialVersionUID = -958724007591692537L;
+
+ @Override
+ protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+ try {
+ confRestClient.set(attrLayout);
+ info(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (Exception e) {
+ LOG.error("While saving layout configuration", e);
+ error(getString(Constants.ERROR) + ": " + e.getMessage());
+ }
+ feedbackPanel.refresh(target);
+ }
+
+ @Override
+ protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+ error(getString(Constants.ERROR) + ": While saving layout configuration");
+ feedbackPanel.refresh(target);
+ }
+ };
+
+ form.add(submit);
+
+ final IndicatingAjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) {
+
+ private static final long serialVersionUID = -958724007591692537L;
+
+ @Override
+ protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+ target.add(container);
+ }
+
+ @Override
+ protected void onError(final AjaxRequestTarget target, final Form<?> form) {
+ }
+ };
+
+ cancel.setDefaultFormProcessing(false);
+ form.add(cancel);
+ container.add(form);
+ add(container);
+ }
+}