[SYNCOPE-156] providing ListView table view + Provision wizard functionalities
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/ba7f1a5c Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/ba7f1a5c Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/ba7f1a5c Branch: refs/heads/SYNCOPE-156 Commit: ba7f1a5ce9f852e9783853b7397a64a66ac4826c Parents: 6ad532a Author: fmartelli <[email protected]> Authored: Wed Aug 12 15:55:08 2015 +0200 Committer: fmartelli <[email protected]> Committed: Wed Aug 12 15:55:08 2015 +0200 ---------------------------------------------------------------------- .../console/pages/BulkActionModalPage.java | 9 +- .../console/pages/ProvisioningModalPage.java | 13 +- .../console/panels/AbstractResourceModal.java | 78 +++++ .../console/panels/ActionDataTablePanel.java | 14 +- .../console/panels/BeanReflectionModal.java | 36 ++ .../console/panels/BeanReflectionPanel.java | 339 +++++++++++++++++++ .../client/console/panels/ConnectorModal.java | 50 +-- .../client/console/panels/ListViewPanel.java | 322 ++++++++++++++++++ .../client/console/panels/ModalContent.java | 8 +- .../console/panels/ResourceMappingPanel.java | 66 ++-- .../client/console/panels/ResourceModal.java | 94 +++-- .../client/console/topology/Topology.java | 337 ++++++++++-------- .../client/console/topology/TopologyNode.java | 5 +- .../console/topology/TopologyNodePanel.java | 47 ++- .../markup/html/form/AbstractFieldPanel.java | 2 +- .../wicket/markup/html/form/ActionLink.java | 23 +- .../markup/html/form/ActionLinksPanel.java | 261 +++++++++++--- .../form/CheckBoxMultipleChoiceFieldPanel.java | 13 +- .../client/console/wizards/AjaxWizard.java | 125 +++++++ .../console/wizards/AjaxWizardButton.java | 66 ++++ .../console/wizards/AjaxWizardButtonBar.java | 111 ++++++ .../client/console/wizards/ProvisionWizard.java | 123 +++++++ .../META-INF/resources/css/syncopeConsole.css | 139 ++++---- .../resources/META-INF/resources/js/topology.js | 90 ++--- .../console/panels/BeanReflectionModal.html | 30 ++ .../console/panels/BeanReflectionPanel.html | 39 +++ .../client/console/panels/ConnectorModal.html | 41 +-- .../client/console/panels/ListViewPanel.html | 60 ++++ .../client/console/panels/ResourceModal.html | 14 +- .../console/panels/ResourceModal.properties | 7 + .../console/panels/ResourceModal_it.properties | 7 + .../panels/ResourceModal_pt_BR.properties | 7 + .../client/console/topology/Topology.html | 21 +- .../console/topology/TopologyNodePanel.html | 59 ++-- .../markup/html/form/ActionLinksPanel.html | 32 +- .../form/CheckBoxMultipleChoiceFieldPanel.html | 8 +- .../wizards/ProvisionWizard$AccountLink.html | 23 ++ .../wizards/ProvisionWizard$Mapping.html | 23 ++ .../wizards/ProvisionWizard$ObjectType.html | 30 ++ .../console/wizards/ProvisionWizard.properties | 24 ++ .../wizards/ProvisionWizard_it.properties | 24 ++ .../wizards/ProvisionWizard_pt_BR.properties | 24 ++ pom.xml | 5 +- 43 files changed, 2350 insertions(+), 499 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/ba7f1a5c/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java index 5567094..6172639 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.client.console.pages; +import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; @@ -39,7 +40,6 @@ import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvid import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; import org.apache.wicket.model.ResourceModel; import org.springframework.beans.BeanUtils; @@ -85,7 +85,8 @@ public class BulkActionModalPage<T, S> extends BaseModalPage { Integer.MAX_VALUE).setVisible(items != null && !items.isEmpty())); @SuppressWarnings("rawtypes") - final ActionLinksPanel actionPanel = new ActionLinksPanel("actions", new Model(), getPageReference()); + final ActionLinksPanel<Serializable> actionPanel + = ActionLinksPanel.builder(getPageReference()).build("actions"); add(actionPanel); for (ActionLink.ActionType action : actions) { @@ -118,12 +119,12 @@ public class BulkActionModalPage<T, S> extends BaseModalPage { LOG.error("Bulk action type not supported"); } - actionPanel.add(new ActionLink() { + actionPanel.add(new ActionLink<Serializable>() { private static final long serialVersionUID = -3722207913631435501L; @Override - public void onClick(final AjaxRequestTarget target) { + public void onClick(final AjaxRequestTarget target, final Serializable ignore) { try { final BulkActionResult res = (BulkActionResult) bulkActionExecutor.getClass(). getMethod("bulkAction", BulkAction.class).invoke(bulkActionExecutor, bulkAction); http://git-wip-us.apache.org/repos/asf/syncope/blob/ba7f1a5c/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java index 9937e36..32a4921 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.client.console.pages; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; @@ -129,12 +130,12 @@ public class ProvisioningModalPage<T extends AnyTO> extends AbstractStatusModalP final String pageId = "Resources"; - table.addAction(new ActionLink() { + table.addAction(new ActionLink<Serializable>() { private static final long serialVersionUID = -3722207913631435501L; @Override - public void onClick(final AjaxRequestTarget target) { + public void onClick(final AjaxRequestTarget target, final Serializable ignore) { try { bulkAssociationAction(target, ResourceDeassociationActionType.UNLINK, table, columns); } catch (Exception e) { @@ -145,12 +146,12 @@ public class ProvisioningModalPage<T extends AnyTO> extends AbstractStatusModalP } }, ActionLink.ActionType.UNLINK, pageId); - table.addAction(new ActionLink() { + table.addAction(new ActionLink<Serializable>() { private static final long serialVersionUID = -3722207913631435501L; @Override - public void onClick(final AjaxRequestTarget target) { + public void onClick(final AjaxRequestTarget target, final Serializable ignore) { try { bulkAssociationAction(target, ResourceDeassociationActionType.DEPROVISION, table, columns); } catch (Exception e) { @@ -161,12 +162,12 @@ public class ProvisioningModalPage<T extends AnyTO> extends AbstractStatusModalP } }, ActionLink.ActionType.DEPROVISION, pageId); - table.addAction(new ActionLink() { + table.addAction(new ActionLink<Serializable>() { private static final long serialVersionUID = -3722207913631435501L; @Override - public void onClick(final AjaxRequestTarget target) { + public void onClick(final AjaxRequestTarget target, final Serializable ignore) { try { bulkAssociationAction(target, ResourceDeassociationActionType.UNASSIGN, table, columns); } catch (Exception e) { http://git-wip-us.apache.org/repos/asf/syncope/blob/ba7f1a5c/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java new file mode 100644 index 0000000..1ed9050 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java @@ -0,0 +1,78 @@ +/* + * 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.io.Serializable; +import org.apache.syncope.client.console.topology.TopologyNode; +import org.apache.wicket.PageReference; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; + +/** + * Modal window with Resource form. + */ +public abstract class AbstractResourceModal extends ModalContent { + + private static final long serialVersionUID = 1734415311027284221L; + + public AbstractResourceModal(final ModalWindow window, final PageReference pageRef) { + super(window, pageRef); + } + + public static class CreateEvent extends ModalEvent { + + private final Serializable key; + + private final String displayName; + + private final Serializable parent; + + private final TopologyNode.Kind kind; + + public CreateEvent( + final Serializable key, + final String displayName, + final TopologyNode.Kind kind, + final Serializable parent, + final AjaxRequestTarget target) { + super(target); + this.key = key; + this.displayName = displayName; + this.kind = kind; + this.parent = parent; + } + + public Serializable getKey() { + return key; + } + + public String getDisplayName() { + return displayName; + } + + public TopologyNode.Kind getKind() { + return kind; + } + + public Serializable getParent() { + return parent; + } + + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/ba7f1a5c/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 index 80d05a1..837c89d 100644 --- 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 @@ -18,6 +18,7 @@ */ package org.apache.syncope.client.console.panels; +import java.io.Serializable; import java.util.Collection; import java.util.List; import org.apache.syncope.client.console.commons.ActionTableCheckGroup; @@ -37,7 +38,6 @@ 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> { @@ -48,7 +48,7 @@ public class ActionDataTablePanel<T, S> extends DataTablePanel<T, S> { private final Form<T> bulkActionForm; - private final ActionLinksPanel actionPanel; + private final ActionLinksPanel<Serializable> actionPanel; private final PageReference pageRef; @@ -93,7 +93,7 @@ public class ActionDataTablePanel<T, S> extends DataTablePanel<T, S> { final WebMarkupContainer actionPanelContainer = new WebMarkupContainer("actionPanelContainer"); bulkActionForm.add(actionPanelContainer); - actionPanel = new ActionLinksPanel("actions", new Model(), pageRef); + actionPanel = ActionLinksPanel.builder(pageRef).build("actions"); actionPanelContainer.add(actionPanel); if (dataTable.getRowCount() == 0) { @@ -111,11 +111,13 @@ public class ActionDataTablePanel<T, S> extends DataTablePanel<T, S> { }.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<Serializable> action, final ActionType type, final String entitlements) { + actionPanel.add(action, type, entitlements, true); } - public void addAction(final ActionLink action, final ActionType type, final String pageId, final boolean enabled) { + public void addAction( + final ActionLink<Serializable> action, final ActionType type, final String pageId, final boolean enabled) { actionPanel.add(action, type, pageId, enabled); } http://git-wip-us.apache.org/repos/asf/syncope/blob/ba7f1a5c/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionModal.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionModal.java new file mode 100644 index 0000000..a6859e8 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionModal.java @@ -0,0 +1,36 @@ +/* + * 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.io.Serializable; +import org.apache.wicket.PageReference; +import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; + +/** + * Modal window with Resource form. + */ +public abstract class BeanReflectionModal extends ModalContent { + + private static final long serialVersionUID = 1734415311027284222L; + + public BeanReflectionModal(final Serializable bean, final ModalWindow window, final PageReference pageRef) { + super(window, pageRef); + add(new BeanReflectionPanel("bean", bean)); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/ba7f1a5c/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionPanel.java new file mode 100644 index 0000000..4f3f1d5 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionPanel.java @@ -0,0 +1,339 @@ +/* + * 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.beans.PropertyDescriptor; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.rest.PolicyRestClient; +import org.apache.syncope.client.console.rest.SchemaRestClient; +import org.apache.syncope.client.console.wicket.markup.html.form.AbstractFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.list.AltListView; +import org.apache.syncope.common.lib.annotation.ClassList; +import org.apache.syncope.common.lib.annotation.SchemaList; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.LoadableDetachableModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.ResourceModel; +import org.apache.wicket.model.util.ListModel; +import org.apache.wicket.spring.injection.annot.SpringBean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.util.ClassUtils; +import org.springframework.util.ReflectionUtils; +import org.springframework.util.ReflectionUtils.FieldCallback; +import org.springframework.util.ReflectionUtils.FieldFilter; + +public class BeanReflectionPanel extends Panel { + + private static final long serialVersionUID = -3035998190456928143L; + + /** + * Logger. + */ + private static final Logger LOG = LoggerFactory.getLogger(BeanReflectionPanel.class); + + @SpringBean + private SchemaRestClient schemaRestClient; + + @SpringBean + private PolicyRestClient policyRestClient; + + private final IModel<List<String>> userSchemas = new LoadableDetachableModel<List<String>>() { + + private static final long serialVersionUID = -2012833443695917883L; + + @Override + protected List<String> load() { + return schemaRestClient.getPlainSchemaNames(); + } + }; + + private final IModel<List<String>> groupSchemas = new LoadableDetachableModel<List<String>>() { + + private static final long serialVersionUID = 5275935387613157437L; + + @Override + protected List<String> load() { + return schemaRestClient.getPlainSchemaNames(); + } + }; + + private final IModel<List<String>> correlationRules = new LoadableDetachableModel<List<String>>() { + + private static final long serialVersionUID = 5275935387613157437L; + + @Override + protected List<String> load() { + return policyRestClient.getCorrelationRuleClasses(); + } + }; + + public BeanReflectionPanel(final String id, final Serializable bean) { + super(id); + + final List<FieldWrapper> items = new ArrayList<>(); + ReflectionUtils.doWithFields(bean.getClass(), + new FieldCallback() { + + @Override + public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException { + FieldWrapper fieldWrapper = new FieldWrapper(); + fieldWrapper.setName(field.getName()); + fieldWrapper.setType(field.getType()); + + final SchemaList schemaList = field.getAnnotation(SchemaList.class); + fieldWrapper.setSchemaList(schemaList); + + final ClassList classList = field.getAnnotation(ClassList.class); + fieldWrapper.setClassList(classList); + + items.add(fieldWrapper); + } + }, + new FieldFilter() { + + @Override + public boolean matches(final Field field) { + return !Modifier.isStatic(field.getModifiers()) && !"serialVersionUID".equals(field.getName()); + } + }); + + final ListView<FieldWrapper> policies = new AltListView<FieldWrapper>("fields", items) { + + private static final long serialVersionUID = 9101744072914090143L; + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected void populateItem(final ListItem<FieldWrapper> item) { + final FieldWrapper field = item.getModelObject(); + + final PropertyDescriptor propDesc = BeanUtils.getPropertyDescriptor(bean.getClass(), field.getName()); + + item.add(new Label("label", new ResourceModel(field.getName()))); + + AbstractFieldPanel component; + try { + if (field.getClassList() != null) { + component = new AjaxDropDownChoicePanel("field", field.getName(), new PropertyModel(bean, + field.getName())); + + final List<String> rules = correlationRules.getObject(); + + if (rules != null && !rules.isEmpty()) { + ((AjaxDropDownChoicePanel) component).setChoices(correlationRules.getObject()); + } + + item.add(component); + + item.add(getActivationControl( + component, + propDesc.getReadMethod().invoke(bean, new Object[] {}) != null, + null, + null)); + + } else if (field.getType().isEnum()) { + component = new AjaxDropDownChoicePanel("field", field.getName(), new PropertyModel(bean, + field.getName())); + + final Serializable[] values = (Serializable[]) field.getType().getEnumConstants(); + + if (values != null && values.length > 0) { + ((AjaxDropDownChoicePanel) component).setChoices(Arrays.asList(values)); + } + + item.add(component); + + item.add(getActivationControl( + component, + (Enum<?>) propDesc.getReadMethod().invoke(bean, new Object[] {}) != null, + values[0], + values[0])); + + } else if (ClassUtils.isAssignable(Boolean.class, field.getType())) { + item.add(new AjaxCheckBoxPanel("check", field.getName(), + new PropertyModel<Boolean>(bean, field.getName()))); + + item.add(new Label("field", new Model(null))); + } else if (Collection.class.isAssignableFrom(field.getType())) { + if (field.getSchemaList() != null) { + final List<String> values = new ArrayList<>(); + if (field.getName().charAt(0) == 'r') { + values.addAll(groupSchemas.getObject()); + + if (field.getSchemaList().extended()) { + values.add("name"); + } + } else { + values.addAll(userSchemas.getObject()); + + if (field.getSchemaList().extended()) { + values.add("key"); + values.add("username"); + } + } + + component = new AjaxPalettePanel("field", new PropertyModel(bean, field.getName()), + new ListModel<>(values)); + item.add(component); + + Collection<?> collection = (Collection) propDesc.getReadMethod().invoke(bean); + item.add(getActivationControl(component, + !collection.isEmpty(), new ArrayList<String>(), new ArrayList<String>())); + } else { + final FieldPanel panel = new AjaxTextFieldPanel("panel", field.getName(), + new Model<String>(null)); + panel.setRequired(true); + + component = new MultiFieldPanel<String>("field", + new PropertyModel(bean, field.getName()), panel); + + item.add(component); + + final List<String> reinitializedValue = new ArrayList<String>(); + + reinitializedValue.add(""); + + item.add(getActivationControl(component, + !((Collection) propDesc.getReadMethod().invoke(bean, new Object[] {})).isEmpty(), + new ArrayList<String>(), (Serializable) reinitializedValue)); + } + } else if (ClassUtils.isAssignable(Number.class, field.getType())) { + component = new SpinnerFieldPanel<Number>("field", field.getName(), + (Class<Number>) field.getType(), new PropertyModel<Number>(bean, field.getName()), + null, null); + item.add(component); + + item.add(getActivationControl(component, + (Integer) propDesc.getReadMethod().invoke(bean, new Object[] {}) > 0, 0, 0)); + } else if (field.getType().equals(String.class)) { + component = new AjaxTextFieldPanel("field", field.getName(), + new PropertyModel(bean, field.getName())); + + item.add(component); + + item.add(getActivationControl(component, + propDesc.getReadMethod().invoke(bean, new Object[] {}) != null, null, null)); + } else { + item.add(new AjaxCheckBoxPanel("check", field.getName(), new Model())); + item.add(new Label("field", new Model(null))); + } + } catch (Exception e) { + LOG.error("Error retrieving bean fields", e); + } + } + }; + + add(policies); + } + + private <T extends Serializable> AjaxCheckBoxPanel getActivationControl(final AbstractFieldPanel<T> panel, + final Boolean checked, final T defaultModelObject, final T reinitializedValue) { + + final AjaxCheckBoxPanel check = new AjaxCheckBoxPanel("check", "check", new Model<Boolean>(checked)); + + panel.setEnabled(checked); + + check.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + if (check.getModelObject()) { + panel.setEnabled(true); + panel.setModelObject(reinitializedValue); + } else { + panel.setModelObject(defaultModelObject); + panel.setEnabled(false); + } + + target.add(panel); + } + }); + + return check; + } + + private static class FieldWrapper implements Serializable { + + private static final long serialVersionUID = -6770429509752964215L; + + private Class<?> type; + + private String name; + + private transient SchemaList schemaList; + + private transient ClassList classList; + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public Class<?> getType() { + return type; + } + + public void setType(final Class<?> type) { + this.type = type; + } + + public SchemaList getSchemaList() { + return schemaList; + } + + public void setSchemaList(final SchemaList schemaList) { + this.schemaList = schemaList; + } + + public ClassList getClassList() { + return classList; + } + + public void setClassList(final ClassList classList) { + this.classList = classList; + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/ba7f1a5c/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java index 40aefce..9db9bd2 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java @@ -30,8 +30,11 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.commons.Constants; import org.apache.syncope.client.console.pages.BasePage; +import org.apache.syncope.client.console.topology.Topology; +import org.apache.syncope.client.console.topology.TopologyNode; 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.CheckBoxMultipleChoiceFieldPanel; import org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel; import org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView; import org.apache.syncope.common.lib.SyncopeClientException; @@ -48,11 +51,11 @@ import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; +import org.apache.wicket.event.Broadcast; import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton; import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.form.CheckBoxMultipleChoice; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.list.ListView; @@ -67,7 +70,7 @@ import org.apache.wicket.validation.validator.RangeValidator; /** * Modal window with Connector form. */ -public class ConnectorModal extends ModalContent { +public class ConnectorModal extends AbstractResourceModal { private static final long serialVersionUID = -2025535531121434050L; @@ -143,14 +146,14 @@ public class ConnectorModal extends ModalContent { connectorForm.add(displayName); final AjaxDropDownChoicePanel<String> location = new AjaxDropDownChoicePanel<>("location", "location", - new Model<>(bundleTO == null ? null : bundleTO.getLocation())); + new Model<>(bundleTO == null ? connInstanceTO.getLocation() : bundleTO.getLocation())); ((DropDownChoice<String>) location.getField()).setNullValid(true); location.setStyleSheet("long_dynamicsize"); location.setChoices(new ArrayList<>(mapConnBundleTOs.keySet())); location.setRequired(true); location.addRequiredLabel(); location.setOutputMarkupId(true); - location.setEnabled(connInstanceTO.getKey() == 0); + location.setEnabled(connInstanceTO.getKey() == 0 && StringUtils.isBlank(connInstanceTO.getLocation())); location.getField().setOutputMarkupId(true); connectorForm.add(location); @@ -160,11 +163,12 @@ public class ConnectorModal extends ModalContent { ((DropDownChoice<String>) connectorName.getField()).setNullValid(true); connectorName.setStyleSheet("long_dynamicsize"); connectorName.setChoices(bundleTO == null - ? new ArrayList<String>() - : new ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).keySet())); + ? StringUtils.isBlank(connInstanceTO.getLocation()) + ? new ArrayList<String>() + : new ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).keySet()) + : new ArrayList<>(mapConnBundleTOs.get(bundleTO.getLocation()).keySet())); connectorName.setRequired(true); connectorName.addRequiredLabel(); - connectorName.setEnabled(connInstanceTO.getLocation() != null); connectorName.setOutputMarkupId(true); connectorName.setEnabled(connInstanceTO.getKey() == 0); connectorName.getField().setOutputMarkupId(true); @@ -176,7 +180,7 @@ public class ConnectorModal extends ModalContent { version.setChoices(bundleTO == null ? new ArrayList<String>() : new ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()). - get(connInstanceTO.getBundleName()).keySet())); + get(connInstanceTO.getBundleName()).keySet())); version.setRequired(true); version.addRequiredLabel(); version.setEnabled(connInstanceTO.getBundleName() != null); @@ -313,19 +317,20 @@ public class ConnectorModal extends ModalContent { connectorPropForm.add(check); // form - third tab (capabilities) - final IModel<List<ConnectorCapability>> capabilities = - new LoadableDetachableModel<List<ConnectorCapability>>() { + final IModel<List<ConnectorCapability>> capabilities + = new LoadableDetachableModel<List<ConnectorCapability>>() { - private static final long serialVersionUID = 5275935387613157437L; + private static final long serialVersionUID = 5275935387613157437L; - @Override - protected List<ConnectorCapability> load() { - return Arrays.asList(ConnectorCapability.values()); - } - }; - CheckBoxMultipleChoice<ConnectorCapability> capabilitiesPalette = new CheckBoxMultipleChoice<>( - "capabilitiesPalette", - new PropertyModel<List<ConnectorCapability>>(this, "selectedCapabilities"), capabilities); + @Override + protected List<ConnectorCapability> load() { + return Arrays.asList(ConnectorCapability.values()); + } + }; + CheckBoxMultipleChoiceFieldPanel<ConnectorCapability> capabilitiesPalette + = new CheckBoxMultipleChoiceFieldPanel<>( + "capabilitiesPalette", + new PropertyModel<List<ConnectorCapability>>(this, "selectedCapabilities"), capabilities); capabilitiesPalette.add(new AjaxFormChoiceComponentUpdatingBehavior() { @@ -373,6 +378,13 @@ public class ConnectorModal extends ModalContent { try { if (connInstanceTO.getKey() == 0) { connectorRestClient.create(conn); + send(pageRef.getPage(), Broadcast.BREADTH, new CreateEvent( + conn.getKey(), + conn.getDisplayName(), + TopologyNode.Kind.CONNECTOR, + conn.getLocation().startsWith(Topology.CONNECTOR_SERVER_LOCATION_PREFIX) + ? conn.getLocation() : Topology.ROOT_NAME, + target)); } else { connectorRestClient.update(conn); } http://git-wip-us.apache.org/repos/asf/syncope/blob/ba7f1a5c/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java new file mode 100644 index 0000000..f89aa9b --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java @@ -0,0 +1,322 @@ +/* + * 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.beans.PropertyDescriptor; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxButton; +import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink; +import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel; +import org.apache.syncope.client.console.wizards.AjaxWizard; +import org.apache.wicket.PageReference; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.event.IEvent; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.markup.html.panel.Fragment; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.ResourceModel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class ListViewPanel<T extends Serializable> extends Panel { + + private static final long serialVersionUID = -7982691107029848579L; + + /** + * Logger. + */ + private static final Logger LOG = LoggerFactory.getLogger(ListViewPanel.class); + + private final ClearIndicatingAjaxButton addButton; + + private AjaxWizard<T> newItemPanel; + + private final WebMarkupContainer container; + + private final Fragment initialFragment; + + private final List<T> listOfItems; + + /** + * Table view of a list of beans. + * + * @param id id. + * @param list list of item. + * @param reference list item reference class. + * @param includes Used to sort and restrict the set of bean's fields to be shown. + * @param actions item actions. + */ + private ListViewPanel( + final String id, + final List<T> list, + final Class<T> reference, + final List<String> includes, + final ActionLinksPanel.Builder<T> actions, + final PageReference pageRef) { + super(id); + setOutputMarkupId(true); + + container = new WebMarkupContainer("container"); + add(container.setOutputMarkupId(true)); + + initialFragment = new Fragment("content", "table", this); + container.addOrReplace(initialFragment); + + initialFragment.add(new Label("caption", new ResourceModel("listview.caption", StringUtils.EMPTY))); + + final List<String> toBeIncluded; + if (includes == null || includes.isEmpty()) { + toBeIncluded = new ArrayList<String>(); + for (Field field : Arrays.asList(reference.getDeclaredFields())) { + toBeIncluded.add(field.getName()); + } + } else { + toBeIncluded = includes; + } + + if (toBeIncluded.isEmpty()) { + LOG.warn("No field has been retrieved from {}", reference.getName()); + listOfItems = Collections.<T>emptyList(); + } else if (list == null || list.isEmpty()) { + LOG.info("No item to be shown"); + listOfItems = Collections.<T>emptyList(); + } else { + listOfItems = list; + if (LOG.isDebugEnabled()) { + for (String field : toBeIncluded) { + LOG.debug("Show field {}", field); + } + } + } + + final ListView<String> names = new ListView<String>("names", toBeIncluded) { + + private static final long serialVersionUID = 1L; + + @Override + protected void populateItem(final ListItem<String> item) { + item.add(new Label("name", new ResourceModel(item.getModelObject(), item.getModelObject()))); + } + }; + initialFragment.add(names); + + final ListView<T> beans = new ListView<T>("beans", listOfItems) { + + private static final long serialVersionUID = 1L; + + @Override + protected void populateItem(final ListItem<T> beanItem) { + final T bean = beanItem.getModelObject(); + + final ListView<String> fields = new ListView<String>("fields", toBeIncluded) { + + private static final long serialVersionUID = 1L; + + @Override + protected void populateItem(final ListItem<String> fieldItem) { + try { + LOG.error("Processing field {}", fieldItem.getModelObject()); + + final Object value = new PropertyDescriptor(fieldItem.getModelObject(), bean.getClass()). + getReadMethod().invoke(bean); + + LOG.error("Field value {}", value); + + fieldItem.add(value == null + ? new Label("field", StringUtils.EMPTY) + : new Label("field", new ResourceModel(value.toString(), value.toString()))); + + } catch (Exception e) { + LOG.error("Error retrieving value for field {}", fieldItem.getModelObject(), e); + fieldItem.add(new Label("field", StringUtils.EMPTY)); + } + } + }; + beanItem.add(fields); + beanItem.add(actions.build("actions", bean)); + } + }; + beans.setReuseItems(true); + initialFragment.add(beans); + + addButton = new ClearIndicatingAjaxButton("add", pageRef) { + + private static final long serialVersionUID = 1L; + + @Override + protected void onSubmitInternal(final AjaxRequestTarget target, final Form<?> form) { + final Fragment fragment = new Fragment("content", "wizard", ListViewPanel.this); + fragment.add(newItemPanel.clone()); + container.addOrReplace(fragment); + target.add(container); + } + }; + + addButton.setEnabled(false); + addButton.setVisible(false); + + initialFragment.add(addButton); + } + + @Override + public void onEvent(final IEvent<?> event) { + if (event.getPayload() instanceof AjaxWizard.NewItemEvent) { + final AjaxRequestTarget target = AjaxWizard.NewItemEvent.class.cast(event.getPayload()).getTarget(); + + @SuppressWarnings("unchecked") + final T item = ((AjaxWizard.NewItemEvent<T>) event.getPayload()).getItem(); + + if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) { + this.listOfItems.add(item); + } + + container.addOrReplace(initialFragment); + target.add(container); + } + super.onEvent(event); + } + + private ListViewPanel<T> addNewItemPanel(final AjaxWizard<T> panel) { + this.newItemPanel = panel; + + if (this.newItemPanel != null) { + addButton.setEnabled(true); + addButton.setVisible(true); + } + + return this; + } + + public static <T extends Serializable> Builder<T> builder(final Class<T> reference, final PageReference pageRef) { + return new Builder<T>(reference, pageRef); + } + + /** + * ListViewPanel builder. + * + * @param <T> list item reference type. + */ + public static final class Builder<T extends Serializable> implements Serializable { + + private static final long serialVersionUID = 1L; + + private final PageReference pageRef; + + private final Class<T> reference; + + private final List<String> includes = new ArrayList<>(); + + private final ActionLinksPanel.Builder<T> actions; + + private List<T> items; + + private AjaxWizard<T> newItemPanel; + + private Builder(final Class<T> reference, final PageReference pageRef) { + this.pageRef = pageRef; + this.reference = reference; + this.items = null; + this.actions = ActionLinksPanel.<T>builder(pageRef); + } + + /** + * Builds a list view. + * + * @param id component id. + * @return List view. + */ + public ListViewPanel<T> build(final String id) { + return new ListViewPanel<T>(id, items, reference, includes, actions, pageRef).addNewItemPanel(newItemPanel); + } + + /** + * Sets list of items. + * + * @param items list of items. + * @return current builder object. + */ + public Builder<T> setItems(final List<T> items) { + this.items = items; + return this; + } + + /** + * Adds item. + * + * @param item item. + * @return current builder object. + */ + public Builder<T> addItem(final T item) { + if (item == null) { + return this; + } + + if (this.items == null) { + this.items = new ArrayList<>(); + } + + this.items.add(item); + return this; + } + + /** + * Gives fields to be shown. It could be used to give an order as well. + * + * @param includes field names to be shown. + * @return current builder object. + */ + public Builder<T> includes(final String... includes) { + for (String include : includes) { + if (include != null && !this.includes.contains(include)) { + this.includes.add(include); + } + } + return this; + } + + /** + * Add item action (the given order is ignored. + * + * @param link action link. + * @param type action type. + * @param entitlements entitlements. + * @return current builder object. + */ + public Builder<T> addAction( + final ActionLink<T> link, final ActionLink.ActionType type, final String entitlements) { + actions.add(link, type, entitlements); + return this; + } + + public Builder<T> addNewItemPanel(final AjaxWizard<T> panel) { + this.newItemPanel = panel; + return this; + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/ba7f1a5c/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java index fbf8802..6a123c0 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ModalContent.java @@ -54,9 +54,9 @@ public class ModalContent extends Panel { protected NotificationPanel feedbackPanel; - private final PageReference pageRef; + protected final PageReference pageRef; - private final ModalWindow window; + protected final ModalWindow window; public ModalContent(final ModalWindow window, final PageReference pageRef) { super(window.getContentId()); @@ -68,6 +68,10 @@ public class ModalContent extends Panel { add(feedbackPanel); } + public NotificationPanel getFeedbackPanel() { + return feedbackPanel; + } + /** * Generic modal event. */ http://git-wip-us.apache.org/repos/asf/syncope/blob/ba7f1a5c/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java index 17ae3bf..b210c86 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java @@ -120,9 +120,9 @@ public class ResourceMappingPanel extends Panel { private final ResourceTO resourceTO; /** - * User / group. + * External resource provisioning configuration instance to be updated. */ - private final AnyTypeKind anyTypeKind; + private final ProvisionTO provisionTO; /** * Mapping container. @@ -134,31 +134,26 @@ public class ResourceMappingPanel extends Panel { private final AjaxCheckBoxPanel connObjectLinkCheckbox; private MappingTO getMapping() { - ProvisionTO provision = resourceTO.getProvision(this.anyTypeKind.name()); - if (provision == null) { - provision = new ProvisionTO(); - resourceTO.getProvisions().add(provision); - } - if (provision.getMapping() == null) { - provision.setMapping(new MappingTO()); + if (provisionTO.getMapping() == null) { + provisionTO.setMapping(new MappingTO()); } - return provision.getMapping(); + return provisionTO.getMapping(); } /** * Attribute Mapping Panel. * * @param id panel id - * @param resourceTO external resource - * @param anyTypeKind USER / GROUP + * @param resourceTO external resource to be updated. + * @param provisionTO external resource provisioning configuration instance. */ - public ResourceMappingPanel(final String id, final ResourceTO resourceTO, final AnyTypeKind anyTypeKind) { + public ResourceMappingPanel(final String id, final ResourceTO resourceTO, final ProvisionTO provisionTO) { super(id); setOutputMarkupId(true); this.resourceTO = resourceTO; - this.anyTypeKind = anyTypeKind; + this.provisionTO = provisionTO == null ? new ProvisionTO() : provisionTO; this.mappingContainer = new WebMarkupContainer("mappingContainer"); this.mappingContainer.setOutputMarkupId(true); @@ -168,9 +163,8 @@ public class ResourceMappingPanel extends Panel { this.connObjectLinkContainer.setOutputMarkupId(true); add(this.connObjectLinkContainer); - if (this.resourceTO.getConnector() != null && this.resourceTO.getConnector() > 0) { - schemaNames = getSchemaNames(this.resourceTO.getConnector(), this.resourceTO.getConnConfProperties()); - + if (resourceTO.getConnector() != null && resourceTO.getConnector() > 0) { + schemaNames = getSchemaNames(resourceTO.getConnector(), resourceTO.getConnConfProperties()); setEnabled(); } else { schemaNames = Collections.<String>emptyList(); @@ -184,7 +178,8 @@ public class ResourceMappingPanel extends Panel { final Label passwordLabel = new Label("passwordLabel", new ResourceModel("password")); mappingContainer.add(passwordLabel); - if (AnyTypeKind.USER != ResourceMappingPanel.this.anyTypeKind) { + + if (!AnyTypeKind.USER.name().equals(this.provisionTO.getAnyType())) { passwordLabel.setVisible(false); } @@ -284,9 +279,9 @@ public class ResourceMappingPanel extends Panel { } }); - final AjaxDropDownChoicePanel<String> intAttrNames = - new AjaxDropDownChoicePanel<>("intAttrNames", getString("intAttrNames"), - new PropertyModel<String>(mapItem, "intAttrName"), false); + final AjaxDropDownChoicePanel<String> intAttrNames = new AjaxDropDownChoicePanel<>("intAttrNames", + getString("intAttrNames"), + new PropertyModel<String>(mapItem, "intAttrName"), false); intAttrNames.setChoices(schemaNames); intAttrNames.setRequired(true); intAttrNames.setStyleSheet(FIELD_STYLE); @@ -301,22 +296,23 @@ public class ResourceMappingPanel extends Panel { item.add(intAttrNames); final List<IntMappingType> attrTypes = new ArrayList<>(getAttributeTypes(entity)); - final AjaxDropDownChoicePanel<IntMappingType> intMappingTypes = - new AjaxDropDownChoicePanel<>("intMappingTypes", - new ResourceModel("intMappingTypes", "intMappingTypes").getObject(), - new PropertyModel<IntMappingType>(mapItem, "intMappingType")); + final AjaxDropDownChoicePanel<IntMappingType> intMappingTypes = new AjaxDropDownChoicePanel<>( + "intMappingTypes", + new ResourceModel("intMappingTypes", "intMappingTypes").getObject(), + new PropertyModel<IntMappingType>(mapItem, "intMappingType")); intMappingTypes.setRequired(true); intMappingTypes.setChoices(attrTypes); intMappingTypes.setStyleSheet(FIELD_STYLE); item.add(intMappingTypes); - final AjaxDropDownChoicePanel<AnyTypeKind> entitiesPanel = - new AjaxDropDownChoicePanel<>("entities", - new ResourceModel("entities", "entities").getObject(), - new Model<>(entity)); - entitiesPanel.setChoices(anyTypeKind == AnyTypeKind.GROUP + final AjaxDropDownChoicePanel<AnyTypeKind> entitiesPanel = new AjaxDropDownChoicePanel<>("entities", + new ResourceModel("entities", "entities").getObject(), + new Model<>(entity)); + + entitiesPanel.setChoices(provisionTO.getAnyType().equals(AnyTypeKind.GROUP.name()) ? Collections.<AnyTypeKind>singletonList(AnyTypeKind.GROUP) : Arrays.asList(AnyTypeKind.values())); + entitiesPanel.setStyleSheet(DEF_FIELD_STYLE); entitiesPanel.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { @@ -399,7 +395,7 @@ public class ResourceMappingPanel extends Panel { } }); item.add(password); - if (AnyTypeKind.USER != ResourceMappingPanel.this.anyTypeKind) { + if (!AnyTypeKind.USER.name().equals(provisionTO.getAnyType())) { password.setVisible(false); } @@ -446,7 +442,7 @@ public class ResourceMappingPanel extends Panel { } }; addMappingBtn.setDefaultFormProcessing(false); - addMappingBtn.setEnabled(this.resourceTO.getConnector() != null && this.resourceTO.getConnector() > 0); + addMappingBtn.setEnabled(resourceTO.getConnector() != null && resourceTO.getConnector() > 0); mappingContainer.add(addMappingBtn); boolean connObjectLinkEnabled = false; @@ -495,10 +491,10 @@ public class ResourceMappingPanel extends Panel { private void setEnabled() { ConnInstanceTO connInstanceTO = new ConnInstanceTO(); - connInstanceTO.setKey(this.resourceTO.getConnector()); - connInstanceTO.getConfiguration().addAll(this.resourceTO.getConnConfProperties()); + connInstanceTO.setKey(resourceTO.getConnector()); + connInstanceTO.getConfiguration().addAll(resourceTO.getConnConfProperties()); - boolean enabled = resourceTO.getProvision(anyTypeKind.name()) != null; + boolean enabled = provisionTO != null; this.mappingContainer.setEnabled(enabled); this.mappingContainer.setVisible(enabled); http://git-wip-us.apache.org/repos/asf/syncope/blob/ba7f1a5c/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java index 8627998..6390f01 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceModal.java @@ -26,10 +26,12 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.Predicate; import org.apache.syncope.client.console.commons.Constants; import org.apache.syncope.client.console.pages.AbstractBasePage; +import org.apache.syncope.client.console.topology.TopologyNode; +import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink; +import org.apache.syncope.client.console.wizards.ProvisionWizard; import org.apache.syncope.common.lib.to.MappingItemTO; import org.apache.syncope.common.lib.to.ProvisionTO; import org.apache.syncope.common.lib.to.ResourceTO; -import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.Entitlement; import org.apache.wicket.PageReference; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -38,6 +40,7 @@ import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDa import org.apache.wicket.event.Broadcast; import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton; import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; +import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.ResourceModel; @@ -45,7 +48,7 @@ import org.apache.wicket.model.ResourceModel; /** * Modal window with Resource form. */ -public class ResourceModal extends ModalContent { +public class ResourceModal extends AbstractResourceModal { private static final long serialVersionUID = 1734415311027284221L; @@ -71,10 +74,61 @@ public class ResourceModal extends ModalContent { //-------------------------------- //-------------------------------- - // Resource mapping panels + // Resource provision panels //-------------------------------- - form.add(new ResourceMappingPanel("umapping", resourceTO, AnyTypeKind.USER)); - form.add(new ResourceMappingPanel("gmapping", resourceTO, AnyTypeKind.GROUP)); + final WebMarkupContainer provisions = new WebMarkupContainer("pcontainer"); + form.add(provisions.setOutputMarkupId(true)); + + final ListViewPanel.Builder<ProvisionTO> builder = ListViewPanel.builder(ProvisionTO.class, pageRef); + builder.setItems(resourceTO.getProvisions()); + builder.includes("anyType", "objectClass"); + + builder.addAction(new ActionLink<ProvisionTO>() { + + private static final long serialVersionUID = -3722207913631435504L; + + @Override + public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) { + + } + }, ActionLink.ActionType.MAPPING, Entitlement.RESOURCE_UPDATE).addAction(new ActionLink<ProvisionTO>() { + + private static final long serialVersionUID = -3722207913631435514L; + + @Override + public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) { + + } + }, ActionLink.ActionType.ACCOUNT_LINK, Entitlement.RESOURCE_UPDATE).addAction(new ActionLink<ProvisionTO>() { + + private static final long serialVersionUID = -3722207913631435524L; + + @Override + public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) { + + } + }, ActionLink.ActionType.RESET_TIME, Entitlement.RESOURCE_UPDATE).addAction(new ActionLink<ProvisionTO>() { + + private static final long serialVersionUID = -3722207913631435534L; + + @Override + public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) { + + } + }, ActionLink.ActionType.CLONE, Entitlement.RESOURCE_CREATE).addAction(new ActionLink<ProvisionTO>() { + + private static final long serialVersionUID = -3722207913631435544L; + + @Override + public void onClick(final AjaxRequestTarget target, final ProvisionTO provisionTO) { + resourceTO.getProvisions().remove(provisionTO); + target.add(provisions); + + } + }, ActionLink.ActionType.DELETE, Entitlement.RESOURCE_DELETE); + + builder.addNewItemPanel(new ProvisionWizard("wizard", resourceTO, pageRef)); + provisions.add(builder.build("provisions")); //-------------------------------- //-------------------------------- @@ -129,7 +183,12 @@ public class ResourceModal extends ModalContent { try { if (createFlag) { resourceRestClient.create(resourceTO); - send(pageRef.getPage(), Broadcast.BREADTH, new ResourceCreateEvent(target, resourceTO)); + send(pageRef.getPage(), Broadcast.BREADTH, new CreateEvent( + resourceTO.getKey(), + resourceTO.getKey(), + TopologyNode.Kind.RESOURCE, + resourceTO.getConnector(), + target)); } else { resourceRestClient.update(resourceTO); } @@ -178,27 +237,4 @@ public class ResourceModal extends ModalContent { MetaDataRoleAuthorizationStrategy.authorize( submit, ENABLE, createFlag ? Entitlement.RESOURCE_CREATE : Entitlement.RESOURCE_UPDATE); } - - public NotificationPanel getFeedbackPanel() { - return feedbackPanel; - } - - public static class ResourceCreateEvent extends ModalEvent { - - private final ResourceTO resourceTO; - - public ResourceCreateEvent(final AjaxRequestTarget target, final ResourceTO resourceTO) { - super(target); - this.resourceTO = resourceTO; - } - - /** - * Create resource getter. - * - * @return created resource. - */ - public ResourceTO getResourceTO() { - return resourceTO; - } - } }
