You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2015/06/08 22:28:05 UTC
[16/17] syncope git commit: [SYNCOPE-156] working with resource and
connector topology
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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..0af8a0b
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
@@ -0,0 +1,346 @@
+/*
+ * 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.PreferenceManager;
+import org.apache.syncope.client.console.commons.AttributableDataProvider;
+import org.apache.syncope.client.console.commons.Constants;
+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 static final int EDIT_MODAL_WIN_HEIGHT = 550;
+
+ /**
+ * Edit modal window width.
+ */
+ private static final int EDIT_MODAL_WIN_WIDTH = 800;
+
+ /**
+ * Schemas to be shown modal window height.
+ */
+ private static final int DISPLAYATTRS_MODAL_WIN_HEIGHT = 550;
+
+ /**
+ * Schemas to be shown modal window width.
+ */
+ private static final int DISPLAYATTRS_MODAL_WIN_WIDTH = 550;
+
+ /**
+ * Schemas to be shown modal window height.
+ */
+ private static final int STATUS_MODAL_WIN_HEIGHT = 500;
+
+ /**
+ * Schemas to be shown modal window width.
+ */
+ private static final int STATUS_MODAL_WIN_WIDTH = 700;
+
+ /**
+ * Application preferences.
+ */
+ @SpringBean
+ protected PreferenceManager prefMan;
+
+ 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(final boolean create) {
+ this.create = create;
+ }
+
+ public int getRows() {
+ return rows;
+ }
+
+ public void setRows(final 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/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountPolicy.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountPolicy.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountPolicy.java
new file mode 100644
index 0000000..60aae41
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AccountPolicy.java
@@ -0,0 +1,35 @@
+/*
+ * 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.markup.html.panel.Panel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AccountPolicy extends Panel {
+
+ private static final long serialVersionUID = -1100228004207271270L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(AccountPolicy.class);
+
+ public AccountPolicy(final String id) {
+ super(id);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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..80d05a1
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ActionDataTablePanel.java
@@ -0,0 +1,145 @@
+/*
+ * 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<>("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<>("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 entitlements) {
+ actionPanel.add(action, type, entitlements);
+ }
+
+ 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/34ec6712/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/34ec6712/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..e809263
--- /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.SyncopeConsoleSession;
+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<>(sysInfoTO.getCreationDate() != null
+ ? SyncopeConsoleSession.get().getDateFormat().format(sysInfoTO.getCreationDate()) : "")));
+ // ------------------------
+
+ // ------------------------
+ // Last change date
+ // ------------------------
+ add(new Label("lastChangeDate", new Model<>(sysInfoTO.getLastChangeDate() != null
+ ? SyncopeConsoleSession.get().getDateFormat().format(sysInfoTO.getCreationDate()) : "")));
+ // ------------------------
+
+ // ------------------------
+ // Creator
+ // ------------------------
+ add(new Label("creator", new Model<>(sysInfoTO.getCreator() != null
+ ? sysInfoTO.getCreator() : "")));
+ // ------------------------
+
+ // ------------------------
+ // Last modifier
+ // ------------------------
+ add(new Label("lastModifier", new Model<>(sysInfoTO.getLastModifier() != null
+ ? sysInfoTO.getLastModifier() : "")));
+ // ------------------------
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/Any.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Any.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Any.java
new file mode 100644
index 0000000..8d99606
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/Any.java
@@ -0,0 +1,35 @@
+/*
+ * 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.markup.html.panel.Panel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Any extends Panel {
+
+ private static final long serialVersionUID = -1100228004207271270L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(Any.class);
+
+ public Any(final String id) {
+ super(id);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java
new file mode 100644
index 0000000..18f28d7
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/Connectors.java
@@ -0,0 +1,385 @@
+/*
+ * 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 static org.apache.wicket.Component.ENABLE;
+import static org.apache.wicket.Component.RENDER;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.PreferenceManager;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.pages.ConnectorModalPage;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
+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.ConnInstanceTO;
+import org.apache.syncope.common.lib.types.Entitlement;
+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.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.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.extensions.markup.html.repeater.util.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.markup.html.panel.Panel;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.StringResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Resources WebPage.
+ */
+public class Connectors extends Panel {
+
+ private static final long serialVersionUID = -3789252860990261728L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(Connectors.class);
+
+ private static final int WIN_HEIGHT = 600;
+
+ private static final int WIN_WIDTH = 1100;
+
+ @SpringBean
+ private ConnectorRestClient connectorRestClient;
+
+ @SpringBean
+ private PreferenceManager prefMan;
+
+ private final ModalWindow createConnectorWin;
+
+ private final ModalWindow editConnectorWin;
+
+ private final int connectorPaginatorRows;
+
+ private WebMarkupContainer connectorContainer;
+
+ /**
+ * Modal window to be used for user status management.
+ */
+ protected final ModalWindow statusmodal = new ModalWindow("statusModal");
+
+ /**
+ * Schemas to be shown modal window height.
+ */
+ private static final int STATUS_MODAL_WIN_HEIGHT = 500;
+
+ /**
+ * Schemas to be shown modal window width.
+ */
+ private static final int STATUS_MODAL_WIN_WIDTH = 700;
+
+ private final PageReference pageRef;
+
+ public Connectors(final String id, final PageReference pageRef) {
+ super(id);
+ this.pageRef = pageRef;
+
+ createConnectorWin = new ModalWindow("createConnectorWin");
+ add(createConnectorWin);
+
+ editConnectorWin = new ModalWindow("editConnectorWin");
+ add(editConnectorWin);
+
+ statusmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+ statusmodal.setInitialHeight(STATUS_MODAL_WIN_HEIGHT);
+ statusmodal.setInitialWidth(STATUS_MODAL_WIN_WIDTH);
+ statusmodal.setCookieName("status-modal");
+ add(statusmodal);
+
+ AjaxLink<Void> reloadLink = new ClearIndicatingAjaxLink<Void>("reloadLink", pageRef) {
+
+ private static final long serialVersionUID = 3109256773218160485L;
+
+ @Override
+ protected void onClickInternal(final AjaxRequestTarget target) {
+ try {
+ connectorRestClient.reload();
+ info(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (Exception e) {
+ error(getString(Constants.ERROR) + ": " + e.getMessage());
+ }
+ ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
+ target.add(connectorContainer);
+ }
+
+ @Override
+ protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+ 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("confirmReloadConnectors") + "')) "
+ + "{return false;} else {return true;}";
+ }
+ };
+ attributes.getAjaxCallListeners().add(ajaxCallListener);
+ }
+ };
+ MetaDataRoleAuthorizationStrategy.authorize(reloadLink, ENABLE, Entitlement.CONNECTOR_RELOAD);
+ add(reloadLink);
+
+ connectorPaginatorRows = prefMan.getPaginatorRows(getRequest(), Constants.PREF_CONNECTORS_PAGINATOR_ROWS);
+
+ setupConnectors();
+ }
+
+ private void setupConnectors() {
+ List<IColumn<ConnInstanceTO, String>> columns = new ArrayList<>();
+
+ columns.add(new PropertyColumn<ConnInstanceTO, String>(
+ new StringResourceModel("key", this, null), "key", "key"));
+ columns.add(new PropertyColumn<ConnInstanceTO, String>(
+ new StringResourceModel("name", this, null), "connectorName", "connectorName"));
+ columns.add(new PropertyColumn<ConnInstanceTO, String>(
+ new StringResourceModel("displayName", this, null), "displayName", "displayName"));
+ columns.add(new PropertyColumn<ConnInstanceTO, String>(
+ new StringResourceModel("bundleName", this, null), "bundleName", "bundleName"));
+ columns.add(new PropertyColumn<ConnInstanceTO, String>(
+ new StringResourceModel("version", this, null), "version", "version"));
+ columns.add(new AbstractColumn<ConnInstanceTO, String>(new StringResourceModel("actions", this, null, "")) {
+
+ private static final long serialVersionUID = 2054811145491901166L;
+
+ @Override
+ public String getCssClass() {
+ return "action";
+ }
+
+ @Override
+ public void populateItem(final Item<ICellPopulator<ConnInstanceTO>> cellItem, final String componentId,
+ final IModel<ConnInstanceTO> model) {
+
+ final ConnInstanceTO connectorTO = model.getObject();
+
+ final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, pageRef);
+
+ panel.add(new ActionLink() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ editConnectorWin.setPageCreator(new ModalWindow.PageCreator() {
+
+ private static final long serialVersionUID = -7834632442532690940L;
+
+ @Override
+ public Page createPage() {
+ return new ConnectorModalPage(Connectors.this.pageRef,
+ editConnectorWin,
+ connectorTO);
+ }
+ });
+
+ editConnectorWin.show(target);
+ }
+ }, ActionLink.ActionType.EDIT, "Connectors");
+
+ panel.add(new ActionLink() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ try {
+ connectorRestClient.delete(connectorTO.getKey());
+ info(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (SyncopeClientException e) {
+ error(getString(Constants.ERROR) + ": " + e.getMessage());
+
+ LOG.error("While deleting connector " + connectorTO.getKey(), e);
+ }
+
+ target.add(connectorContainer);
+ ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
+ }
+ }, ActionLink.ActionType.DELETE, "Connectors");
+
+ cellItem.add(panel);
+ }
+ });
+
+ final AjaxDataTablePanel<ConnInstanceTO, String> table = new AjaxDataTablePanel<>(
+ "connectorDatatable",
+ columns,
+ (ISortableDataProvider<ConnInstanceTO, String>) new ConnectorsProvider(),
+ connectorPaginatorRows,
+ Arrays.asList(new ActionLink.ActionType[] { ActionLink.ActionType.DELETE }),
+ connectorRestClient,
+ "key",
+ "Connectors",
+ pageRef);
+
+ connectorContainer = new WebMarkupContainer("connectorContainer");
+ connectorContainer.add(table);
+ connectorContainer.setOutputMarkupId(true);
+
+ MetaDataRoleAuthorizationStrategy.authorize(connectorContainer, RENDER, Entitlement.CONNECTOR_LIST);
+
+ add(connectorContainer);
+
+ ((BasePage) pageRef.getPage()).setWindowClosedCallback(createConnectorWin, connectorContainer);
+ ((BasePage) pageRef.getPage()).setWindowClosedCallback(editConnectorWin, connectorContainer);
+
+ createConnectorWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+ createConnectorWin.setInitialHeight(WIN_HEIGHT);
+ createConnectorWin.setInitialWidth(WIN_WIDTH);
+ createConnectorWin.setCookieName("create-conn-modal");
+
+ editConnectorWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
+ editConnectorWin.setInitialHeight(WIN_HEIGHT);
+ editConnectorWin.setInitialWidth(WIN_WIDTH);
+ editConnectorWin.setCookieName("edit-conn-modal");
+
+ AjaxLink<Void> createConnectorLink
+ = new ClearIndicatingAjaxLink<Void>("createConnectorLink", pageRef) {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ protected void onClickInternal(final AjaxRequestTarget target) {
+ createConnectorWin.setPageCreator(new ModalWindow.PageCreator() {
+
+ private static final long serialVersionUID = -7834632442532690940L;
+
+ @Override
+ public Page createPage() {
+ ConnectorModalPage form = new ConnectorModalPage(
+ pageRef, editConnectorWin, new ConnInstanceTO());
+ return form;
+ }
+ });
+
+ createConnectorWin.show(target);
+ }
+ };
+
+ MetaDataRoleAuthorizationStrategy.authorize(createConnectorLink, ENABLE, Entitlement.CONNECTOR_CREATE);
+
+ add(createConnectorLink);
+
+ @SuppressWarnings("rawtypes")
+ Form paginatorForm = new Form("connectorPaginatorForm");
+
+ MetaDataRoleAuthorizationStrategy.authorize(paginatorForm, RENDER, Entitlement.CONNECTOR_LIST);
+
+ final DropDownChoice<Integer> rowsChooser = new DropDownChoice<>(
+ "rowsChooser",
+ new PropertyModel<Integer>(this,
+ "connectorPaginatorRows"),
+ 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_CONNECTORS_PAGINATOR_ROWS,
+ String.valueOf(connectorPaginatorRows));
+ table.setItemsPerPage(connectorPaginatorRows);
+
+ target.add(connectorContainer);
+ }
+ });
+
+ paginatorForm.add(rowsChooser);
+ add(paginatorForm);
+ }
+
+ private class ConnectorsProvider extends SortableDataProvider<ConnInstanceTO, String> {
+
+ private static final long serialVersionUID = 4445909568349448518L;
+
+ private final SortableDataProviderComparator<ConnInstanceTO> comparator;
+
+ public ConnectorsProvider() {
+ super();
+ //Default sorting
+ setSort("key", SortOrder.ASCENDING);
+ comparator = new SortableDataProviderComparator<>(this);
+ }
+
+ @Override
+ public Iterator<ConnInstanceTO> iterator(final long first, final long count) {
+ List<ConnInstanceTO> list = connectorRestClient.getAllConnectors();
+
+ Collections.sort(list, comparator);
+
+ return list.subList((int) first, (int) first + (int) count).iterator();
+ }
+
+ @Override
+ public long size() {
+ return connectorRestClient.getAllConnectors().size();
+ }
+
+ @Override
+ public IModel<ConnInstanceTO> model(final ConnInstanceTO connector) {
+
+ return new AbstractReadOnlyModel<ConnInstanceTO>() {
+
+ private static final long serialVersionUID = -6033068018293569398L;
+
+ @Override
+ public ConnInstanceTO getObject() {
+ return connector;
+ }
+ };
+ }
+ }
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ if (event.getPayload() instanceof AbstractSearchResultPanel.EventDataWrapper) {
+ ((AbstractSearchResultPanel.EventDataWrapper) event.getPayload()).getTarget().add(connectorContainer);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/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..1800d54
--- /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 final Collection<T> values = new HashSet<>();
+
+ @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<>(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<>();
+
+ 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/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/PasswordPolicy.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/PasswordPolicy.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/PasswordPolicy.java
new file mode 100644
index 0000000..8bad8ff
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/PasswordPolicy.java
@@ -0,0 +1,35 @@
+/*
+ * 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.markup.html.panel.Panel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PasswordPolicy extends Panel {
+
+ private static final long serialVersionUID = -1100228004207271270L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(PasswordPolicy.class);
+
+ public PasswordPolicy(final String id) {
+ super(id);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
new file mode 100644
index 0000000..f31c87c
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java
@@ -0,0 +1,49 @@
+/*
+ * 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.common.lib.to.RealmTO;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Realm extends Panel {
+
+ private static final long serialVersionUID = -1100228004207271270L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(Realm.class);
+
+ private final RealmTO realmTO;
+
+ public Realm(final String id, final RealmTO realmTO) {
+ super(id);
+ this.realmTO = realmTO;
+
+ add(new RealmDetails("details", realmTO));
+ add(new Any("users"));
+ add(new Any("groups"));
+ add(new Any("services"));
+ add(new Any("serviceRoles"));
+ add(new Any("contexts"));
+ add(new Any("enactmentEngine"));
+ add(new AccountPolicy("accountPolicy"));
+ add(new PasswordPolicy("passwordPolicy"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
new file mode 100644
index 0000000..391dba2
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java
@@ -0,0 +1,41 @@
+/*
+ * 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.common.lib.to.RealmTO;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.PropertyModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RealmDetails extends Panel {
+
+ private static final long serialVersionUID = -1100228004207271270L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(RealmDetails.class);
+
+ public RealmDetails(final String id, final RealmTO realmTO) {
+ super(id);
+ add(new TextField<>("id", new PropertyModel<>(realmTO, "key")).setEnabled(false));
+ add(new TextField<>("name", new PropertyModel<>(realmTO, "name")).setEnabled(false));
+ add(new TextField<>("path", new PropertyModel<>(realmTO, "fullPath")).setEnabled(false));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
new file mode 100644
index 0000000..c1d01e0
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
@@ -0,0 +1,189 @@
+/*
+ * 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.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.client.console.pages.BaseModalPage;
+import org.apache.syncope.client.console.pages.ResourceModalPage.ResourceEvent;
+import org.apache.syncope.client.console.panels.ResourceDetailsPanel.DetailsModEvent;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel.MultiValueSelectorEvent;
+import org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.event.Broadcast;
+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.Form;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public class ResourceConnConfPanel extends Panel {
+
+ private static final long serialVersionUID = -7982691107029848579L;
+
+ @SpringBean
+ private ConnectorRestClient restClient;
+
+ private final ResourceTO resourceTO;
+
+ private final boolean createFlag;
+
+ private List<ConnConfProperty> connConfProperties;
+
+ private WebMarkupContainer connConfPropContainer;
+
+ private AjaxButton check;
+
+ public ResourceConnConfPanel(final String id, final ResourceTO resourceTO, final boolean createFlag) {
+ super(id);
+ setOutputMarkupId(true);
+
+ this.createFlag = createFlag;
+ this.resourceTO = resourceTO;
+
+ connConfProperties = getConnConfProperties();
+
+ connConfPropContainer = new WebMarkupContainer("connectorPropertiesContainer");
+ connConfPropContainer.setOutputMarkupId(true);
+ add(connConfPropContainer);
+
+ /*
+ * the list of overridable connector properties
+ */
+ final ListView<ConnConfProperty> connPropView = new ConnConfPropertyListView("connectorProperties",
+ new PropertyModel<List<ConnConfProperty>>(this, "connConfProperties"),
+ false, resourceTO.getConnConfProperties());
+ connPropView.setOutputMarkupId(true);
+ connConfPropContainer.add(connPropView);
+
+ check = new IndicatingAjaxButton("check", new ResourceModel("check")) {
+
+ private static final long serialVersionUID = -4199438518229098169L;
+
+ @Override
+ public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+ final ResourceTO to = (ResourceTO) form.getModelObject();
+
+ if (restClient.check(to)) {
+ info(getString("success_connection"));
+ } else {
+ error(getString("error_connection"));
+ }
+
+ ((BaseModalPage) getPage()).getFeedbackPanel().refresh(target);
+ }
+ };
+
+ check.setEnabled(!connConfProperties.isEmpty());
+ check.setVisible(!connConfProperties.isEmpty());
+
+ connConfPropContainer.add(check);
+ }
+
+ /**
+ * Get overridable properties.
+ *
+ * @return overridable properties.
+ */
+ private List<ConnConfProperty> getConnConfProperties() {
+ final List<ConnConfProperty> props = new ArrayList<ConnConfProperty>();
+ final Long connectorId = resourceTO.getConnectorId();
+ if (connectorId != null && connectorId > 0) {
+ for (ConnConfProperty property : restClient.getConnectorProperties(connectorId)) {
+ if (property.isOverridable()) {
+ props.add(property);
+ }
+ }
+ }
+ if (createFlag || resourceTO.getConnConfProperties().isEmpty()) {
+ resourceTO.getConnConfProperties().clear();
+ } else {
+ Map<String, ConnConfProperty> valuedProps = new HashMap<String, ConnConfProperty>();
+ for (ConnConfProperty prop : resourceTO.getConnConfProperties()) {
+ valuedProps.put(prop.getSchema().getName(), prop);
+ }
+
+ for (int i = 0; i < props.size(); i++) {
+ if (valuedProps.containsKey(props.get(i).getSchema().getName())) {
+ props.set(i, valuedProps.get(props.get(i).getSchema().getName()));
+ }
+ }
+ }
+
+ // re-order properties
+ Collections.sort(props);
+
+ return props;
+ }
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ AjaxRequestTarget target = null;
+ if (event.getPayload() instanceof DetailsModEvent) {
+ // connector change: update properties and forward event
+ target = ((ResourceEvent) event.getPayload()).getTarget();
+
+ connConfProperties = getConnConfProperties();
+ check.setEnabled(!connConfProperties.isEmpty());
+
+ target.add(connConfPropContainer);
+ } else if (event.getPayload() instanceof MultiValueSelectorEvent) {
+ // multi value connector property change: forward event
+ target = ((MultiValueSelectorEvent) event.getPayload()).getTarget();
+ }
+
+ if (target != null) {
+ send(getPage(), Broadcast.BREADTH, new ConnConfModEvent(target, connConfProperties));
+ }
+ }
+
+ /**
+ * Connector configuration properties modification event.
+ */
+ public static class ConnConfModEvent extends ResourceEvent {
+
+ private List<ConnConfProperty> configuration;
+
+ /**
+ * Constructor.
+ *
+ * @param target request target.
+ * @param configuration connector configuration properties.
+ */
+ public ConnConfModEvent(final AjaxRequestTarget target, final List<ConnConfProperty> configuration) {
+ super(target);
+ this.configuration = configuration;
+ }
+
+ public List<ConnConfProperty> getConfiguration() {
+ return configuration;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34ec6712/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
new file mode 100644
index 0000000..3bff23f
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
@@ -0,0 +1,306 @@
+/*
+ * 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.Arrays;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.pages.ResourceModalPage.ResourceEvent;
+import org.apache.syncope.client.console.rest.ConnectorRestClient;
+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.AjaxTextFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.PropagationMode;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.ChoiceRenderer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ResourceDetailsPanel extends Panel {
+
+ private static final long serialVersionUID = -7982691107029848579L;
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(ResourceDetailsPanel.class);
+
+ @SpringBean
+ private ConnectorRestClient connRestClient;
+
+ private ConnInstanceTO connInstanceTO;
+
+ public ResourceDetailsPanel(final String id, final ResourceTO resourceTO, final List<String> actionClassNames,
+ final boolean createFlag) {
+
+ super(id);
+ setOutputMarkupId(true);
+
+ final AjaxTextFieldPanel resourceName = new AjaxTextFieldPanel("name", new ResourceModel("name", "name").
+ getObject(), new PropertyModel<String>(resourceTO, "key"));
+
+ resourceName.setEnabled(createFlag);
+ resourceName.addRequiredLabel();
+ add(resourceName);
+
+ final AjaxCheckBoxPanel enforceMandatoryCondition = new AjaxCheckBoxPanel("enforceMandatoryCondition",
+ new ResourceModel("enforceMandatoryCondition", "enforceMandatoryCondition").getObject(),
+ new PropertyModel<Boolean>(resourceTO, "enforceMandatoryCondition"));
+ add(enforceMandatoryCondition);
+
+ final AjaxCheckBoxPanel propagationPrimary = new AjaxCheckBoxPanel("propagationPrimary", new ResourceModel(
+ "propagationPrimary", "propagationPrimary").getObject(), new PropertyModel<Boolean>(resourceTO,
+ "propagationPrimary"));
+ add(propagationPrimary);
+
+ final SpinnerFieldPanel<Integer> propagationPriority =
+ new SpinnerFieldPanel<>("propagationPriority", "propagationPriority", Integer.class,
+ new PropertyModel<Integer>(resourceTO, "propagationPriority"), null, null);
+ add(propagationPriority);
+
+ final AjaxDropDownChoicePanel<PropagationMode> propagationMode = new AjaxDropDownChoicePanel<>(
+ "propagationMode", new ResourceModel("propagationMode", "propagationMode").getObject(),
+ new PropertyModel<PropagationMode>(resourceTO, "propagationMode"));
+ propagationMode.setChoices(Arrays.asList(PropagationMode.values()));
+ add(propagationMode);
+
+ final AjaxCheckBoxPanel randomPwdIfNotProvided = new AjaxCheckBoxPanel("randomPwdIfNotProvided",
+ new ResourceModel("randomPwdIfNotProvided", "randomPwdIfNotProvided").getObject(),
+ new PropertyModel<Boolean>(resourceTO, "randomPwdIfNotProvided"));
+ add(randomPwdIfNotProvided);
+
+ final WebMarkupContainer propagationActionsClassNames = new WebMarkupContainer("propagationActionsClassNames");
+ propagationActionsClassNames.setOutputMarkupId(true);
+ add(propagationActionsClassNames);
+
+ final AjaxLink<Void> first = new IndicatingAjaxLink<Void>("first") {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ resourceTO.getPropagationActionsClassNames().add(StringUtils.EMPTY);
+ setVisible(false);
+ target.add(propagationActionsClassNames);
+ }
+ };
+ first.setOutputMarkupPlaceholderTag(true);
+ first.setVisible(resourceTO.getPropagationActionsClassNames().isEmpty());
+ propagationActionsClassNames.add(first);
+
+ final ListView<String> actionsClasses = new ListView<String>("actionsClasses",
+ new PropertyModel<List<String>>(resourceTO, "propagationActionsClassNames")) {
+
+ private static final long serialVersionUID = 9101744072914090143L;
+
+ @Override
+ protected void populateItem(final ListItem<String> item) {
+ final String className = item.getModelObject();
+
+ final DropDownChoice<String> actionsClass = new DropDownChoice<>(
+ "actionsClass", new Model<>(className), actionClassNames);
+ actionsClass.setNullValid(true);
+ actionsClass.setRequired(true);
+ actionsClass.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ resourceTO.getPropagationActionsClassNames().
+ set(item.getIndex(), actionsClass.getModelObject());
+ }
+ });
+ actionsClass.setRequired(true);
+ actionsClass.setOutputMarkupId(true);
+ actionsClass.setRequired(true);
+ item.add(actionsClass);
+
+ AjaxLink<Void> minus = new IndicatingAjaxLink<Void>("drop") {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ resourceTO.getPropagationActionsClassNames().remove(className);
+ first.setVisible(resourceTO.getPropagationActionsClassNames().isEmpty());
+ target.add(propagationActionsClassNames);
+ }
+ };
+ item.add(minus);
+
+ final AjaxLink<Void> plus = new IndicatingAjaxLink<Void>("add") {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ resourceTO.getPropagationActionsClassNames().add(StringUtils.EMPTY);
+ target.add(propagationActionsClassNames);
+ }
+ };
+ plus.setOutputMarkupPlaceholderTag(true);
+ plus.setVisible(item.getIndex() == resourceTO.getPropagationActionsClassNames().size() - 1);
+ item.add(plus);
+ }
+ };
+ propagationActionsClassNames.add(actionsClasses);
+
+ final AjaxDropDownChoicePanel<TraceLevel> createTraceLevel = new AjaxDropDownChoicePanel<>(
+ "createTraceLevel", new ResourceModel("createTraceLevel", "createTraceLevel").getObject(),
+ new PropertyModel<TraceLevel>(resourceTO, "createTraceLevel"));
+ createTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
+ add(createTraceLevel);
+
+ final AjaxDropDownChoicePanel<TraceLevel> updateTraceLevel = new AjaxDropDownChoicePanel<>(
+ "updateTraceLevel", new ResourceModel("updateTraceLevel", "updateTraceLevel").getObject(),
+ new PropertyModel<TraceLevel>(resourceTO, "updateTraceLevel"));
+ updateTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
+ add(updateTraceLevel);
+
+ final AjaxDropDownChoicePanel<TraceLevel> deleteTraceLevel = new AjaxDropDownChoicePanel<>(
+ "deleteTraceLevel", new ResourceModel("deleteTraceLevel", "deleteTraceLevel").getObject(),
+ new PropertyModel<TraceLevel>(resourceTO, "deleteTraceLevel"));
+ deleteTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
+ add(deleteTraceLevel);
+
+ final AjaxDropDownChoicePanel<TraceLevel> syncTraceLevel = new AjaxDropDownChoicePanel<>(
+ "syncTraceLevel", new ResourceModel("syncTraceLevel", "syncTraceLevel").getObject(),
+ new PropertyModel<TraceLevel>(resourceTO, "syncTraceLevel"));
+ syncTraceLevel.setChoices(Arrays.asList(TraceLevel.values()));
+ add(syncTraceLevel);
+
+ final IModel<List<ConnInstanceTO>> connectors = new LoadableDetachableModel<List<ConnInstanceTO>>() {
+
+ private static final long serialVersionUID = 5275935387613157437L;
+
+ @Override
+ protected List<ConnInstanceTO> load() {
+ return connRestClient.getAllConnectors();
+ }
+ };
+
+ connInstanceTO = getConectorInstanceTO(connectors.getObject(), resourceTO);
+
+ final AjaxDropDownChoicePanel<ConnInstanceTO> conn = new AjaxDropDownChoicePanel<>("connector",
+ new ResourceModel("connector", "connector").getObject(),
+ new PropertyModel<ConnInstanceTO>(this, "connInstanceTO"));
+ conn.setChoices(connectors.getObject());
+ conn.setChoiceRenderer(new ChoiceRenderer("displayName", "key"));
+
+ conn.getField().setModel(new IModel<ConnInstanceTO>() {
+
+ private static final long serialVersionUID = -4202872830392400310L;
+
+ @Override
+ public ConnInstanceTO getObject() {
+ return connInstanceTO;
+ }
+
+ @Override
+ public void setObject(final ConnInstanceTO connector) {
+ resourceTO.setConnectorId(connector.getKey());
+ connInstanceTO = connector;
+ }
+
+ @Override
+ public void detach() {
+ }
+ });
+
+ conn.addRequiredLabel();
+ conn.setEnabled(createFlag);
+
+ conn.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ send(getPage(), Broadcast.BREADTH, new DetailsModEvent(target));
+ }
+ });
+
+ add(conn);
+ }
+
+ /**
+ * Get the connetorTO linked to the resource.
+ *
+ * @param connectorTOs list of all connectors.
+ * @param resourceTO resource.
+ * @return selected connector instance: in case of no connectors available, null; in case of new resource
+ * specification, the first on connector available
+ */
+ private ConnInstanceTO getConectorInstanceTO(final List<ConnInstanceTO> connectorTOs, final ResourceTO resourceTO) {
+ if (connectorTOs.isEmpty()) {
+ resourceTO.setConnectorId(null);
+ return null;
+ } else {
+ // use the first element as default
+ ConnInstanceTO res = connectorTOs.get(0);
+
+ for (ConnInstanceTO to : connectorTOs) {
+ if (Long.valueOf(to.getKey()).equals(resourceTO.getConnectorId())) {
+ res = to;
+ }
+ }
+
+ // in case of no match
+ resourceTO.setConnectorId(res.getKey());
+
+ return res;
+ }
+ }
+
+ /**
+ * Connector instance modification event.
+ */
+ public static class DetailsModEvent extends ResourceEvent {
+
+ /**
+ * Constructor.
+ *
+ * @param target request target.
+ */
+ public DetailsModEvent(final AjaxRequestTarget target) {
+ super(target);
+ }
+ }
+}