Repository: syncope Updated Branches: refs/heads/2_0_X a8d5d0527 -> 78b68bf4b
[SYNCOPE-1053] Handling previous object and new object during approval Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/78b68bf4 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/78b68bf4 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/78b68bf4 Branch: refs/heads/2_0_X Commit: 78b68bf4b84a1ad79d4ba246f4030e02344cbbfb Parents: a8d5d05 Author: fmartelli <fabio.marte...@gmail.com> Authored: Tue Jun 13 14:04:38 2017 +0200 Committer: fmartelli <fabio.marte...@gmail.com> Committed: Fri Jun 16 09:42:16 2017 +0200 ---------------------------------------------------------------------- .../console/approvals/ApprovalDetails.java | 18 +++++- .../console/layout/FormLayoutInfoUtils.java | 27 ++++++--- .../wicket/ajax/markup/html/LabelInfo.java | 62 +++++++++++++++++++ .../markup/html/form/AbstractFieldPanel.java | 3 +- .../markup/html/form/AjaxSpinnerFieldPanel.java | 6 +- .../console/wizards/any/AbstractAttrs.java | 9 ++- .../console/wizards/any/AnyWizardBuilder.java | 16 ++--- .../client/console/wizards/any/AuxClasses.java | 22 ++++++- .../client/console/wizards/any/DerAttrs.java | 4 +- .../client/console/wizards/any/Groups.java | 64 +++++++++++++++++--- .../client/console/wizards/any/PlainAttrs.java | 50 ++++++++++++--- .../console/wizards/any/Relationships.java | 27 ++++++++- .../client/console/wizards/any/Resources.java | 18 +++++- .../client/console/wizards/any/Roles.java | 21 ++++++- .../client/console/wizards/any/UserDetails.java | 7 +++ .../wizards/any/UserTemplateWizardBuilder.java | 2 +- .../console/wizards/any/UserWizardBuilder.java | 27 ++++++++- .../client/console/wizards/any/UserWrapper.java | 10 +++ .../client/console/wizards/any/VirAttrs.java | 32 +++++++--- .../client/console/wizards/any/AuxClasses.html | 1 + .../client/console/wizards/any/Groups.html | 1 + .../console/wizards/any/Relationships.html | 4 ++ .../client/console/wizards/any/Resources.html | 1 + .../client/console/wizards/any/Roles.html | 3 +- .../syncope/common/lib/AnyOperations.java | 15 +---- 25 files changed, 376 insertions(+), 74 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDetails.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDetails.java index d2d9c41..c14dab9 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDetails.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDetails.java @@ -21,9 +21,10 @@ package org.apache.syncope.client.console.approvals; import org.apache.syncope.client.console.layout.UserFormLayoutInfo; import org.apache.syncope.client.console.panels.MultilevelPanel; import org.apache.syncope.client.console.rest.AnyTypeRestClient; -import org.apache.syncope.client.console.rest.UserRestClient; import org.apache.syncope.client.console.wizards.AjaxWizard; import org.apache.syncope.client.console.wizards.any.UserWizardBuilder; +import org.apache.syncope.common.lib.AnyOperations; +import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.lib.to.WorkflowFormTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.wicket.PageReference; @@ -35,7 +36,20 @@ public class ApprovalDetails extends MultilevelPanel.SecondLevel { public ApprovalDetails(final PageReference pageRef, final WorkflowFormTO formTO) { super(MultilevelPanel.SECOND_LEVEL_ID); - add(new UserWizardBuilder(new UserRestClient().read(formTO.getUsername()), + final UserTO newUserTO; + final UserTO previousUserTO; + if (formTO.getUserPatch() == null) { + newUserTO = formTO.getUserTO(); + previousUserTO = null; + } else { + formTO.getUserTO().setKey(formTO.getUserPatch().getKey()); + newUserTO = AnyOperations.patch(formTO.getUserTO(), formTO.getUserPatch()); + previousUserTO = formTO.getUserTO(); + } + + add(new UserWizardBuilder( + previousUserTO, + newUserTO, new AnyTypeRestClient().read(AnyTypeKind.USER.name()).getClasses(), new UserFormLayoutInfo(), pageRef). http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/layout/FormLayoutInfoUtils.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/layout/FormLayoutInfoUtils.java b/client/console/src/main/java/org/apache/syncope/client/console/layout/FormLayoutInfoUtils.java index a5caccb..58afe2c 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/layout/FormLayoutInfoUtils.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/layout/FormLayoutInfoUtils.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,6 +32,7 @@ import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.rest.RoleRestClient; import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.AnyTypeTO; +import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.wicket.PageReference; @@ -127,13 +129,24 @@ public final class FormLayoutInfoUtils { final PageReference pageRef) { try { - return anyFormLayout.getFormClass().getConstructor( - anyTO.getClass(), - List.class, - anyFormLayout.getClass(), - pageRef.getClass()). - newInstance(anyTO, anyTypeClasses, anyFormLayout, pageRef); - } catch (Exception e) { + if (anyTO instanceof UserTO) { + return anyFormLayout.getFormClass().getConstructor( + anyTO.getClass(), // previous + anyTO.getClass(), // actual + List.class, + anyFormLayout.getClass(), + pageRef.getClass()). + newInstance(null, anyTO, anyTypeClasses, anyFormLayout, pageRef); + } else { + return anyFormLayout.getFormClass().getConstructor( + anyTO.getClass(), // actual + List.class, + anyFormLayout.getClass(), + pageRef.getClass()). + newInstance(anyTO, anyTypeClasses, anyFormLayout, pageRef); + } + } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { throw new IllegalArgumentException("Could not instantiate " + anyFormLayout.getFormClass().getName(), e); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/LabelInfo.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/LabelInfo.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/LabelInfo.java new file mode 100644 index 0000000..7857f0e --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/markup/html/LabelInfo.java @@ -0,0 +1,62 @@ +/* + * 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.wicket.ajax.markup.html; + +import java.util.Collection; +import org.apache.commons.lang3.StringUtils; +import org.apache.wicket.markup.ComponentTag; +import org.apache.wicket.markup.html.basic.Label; +import org.springframework.util.CollectionUtils; + +public class LabelInfo extends Label { + + private static final long serialVersionUID = 4755868673082976208L; + + private final String title; + + public LabelInfo(final String id, final String title) { + super(id, StringUtils.EMPTY); + this.title = title == null ? StringUtils.EMPTY : StringUtils.abbreviate(title, 30); + } + + public LabelInfo(final String id, final Collection<String> title) { + super(id, StringUtils.EMPTY); + if (CollectionUtils.isEmpty(title)) { + this.title = StringUtils.EMPTY; + } else { + StringBuilder titleBuilder = new StringBuilder(); + for (String el : title) { + if (titleBuilder.length() > 0) { + titleBuilder.append("; "); + } + if (StringUtils.isNoneEmpty(el)) { + titleBuilder.append(el); + } + } + this.title = StringUtils.abbreviate(titleBuilder.toString(), 50); + } + } + + @Override + protected void onComponentTag(final ComponentTag tag) { + tag.put("class", "fa fa-info-circle"); + tag.put("style", "color:red"); + tag.put("title", title); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java index ba2263b..305a97b 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractFieldPanel.java @@ -21,7 +21,6 @@ package org.apache.syncope.client.console.wicket.markup.html.form; import org.apache.commons.lang3.StringUtils; import org.apache.wicket.Component; import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.form.FormComponent; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.IModel; @@ -71,7 +70,7 @@ public abstract class AbstractFieldPanel<T> extends Panel { return this; } - public AbstractFieldPanel<T> showExternAction(final FormComponent<?> component) { + public AbstractFieldPanel<T> showExternAction(final Component component) { final Fragment fragment = new Fragment("externalAction", "externalActionFragment", AbstractFieldPanel.this); addOrReplace(fragment); fragment.add(component.setRenderBodyOnly(false)); http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxSpinnerFieldPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxSpinnerFieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxSpinnerFieldPanel.java index 12d315f..ae8729a 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxSpinnerFieldPanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxSpinnerFieldPanel.java @@ -25,6 +25,8 @@ import com.googlecode.wicket.jquery.ui.form.spinner.SpinnerAdapter; import com.googlecode.wicket.jquery.ui.form.spinner.SpinnerBehavior; import java.io.Serializable; import java.util.List; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.syncope.client.console.commons.Constants; import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; @@ -33,7 +35,6 @@ import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.ResourceModel; -import org.springframework.util.StringUtils; public final class AjaxSpinnerFieldPanel<T extends Number> extends FieldPanel<T> { @@ -97,7 +98,8 @@ public final class AjaxSpinnerFieldPanel<T extends Number> extends FieldPanel<T> public T getObject() { T value = null; - if (list != null && !list.isEmpty() && StringUtils.hasText(list.get(0).toString())) { + if (CollectionUtils.isNotEmpty(list) + && list.get(0) != null && StringUtils.isNotBlank(list.get(0).toString())) { value = reference.equals(Integer.class) ? reference.cast(NumberUtils.toInt(list.get(0).toString())) : reference.equals(Long.class) http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java index 7d9687c..88a792c 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java @@ -74,7 +74,10 @@ public abstract class AbstractAttrs<S extends AbstractSchemaTO> extends WizardSt private final List<String> anyTypeClasses; - public AbstractAttrs(final AnyTO anyTO, final List<String> anyTypeClasses, final List<String> whichAttrs) { + public AbstractAttrs( + final AnyWrapper<?> modelObject, + final List<String> anyTypeClasses, + final List<String> whichAttrs) { super(); this.anyTypeClasses = anyTypeClasses; this.attrTOs = new ListModel<>(Collections.<AttrTO>emptyList()); @@ -82,7 +85,7 @@ public abstract class AbstractAttrs<S extends AbstractSchemaTO> extends WizardSt this.setOutputMarkupId(true); - this.anyTO = anyTO; + this.anyTO = modelObject.getInnerObject(); this.whichAttrs = whichAttrs; } @@ -197,7 +200,7 @@ public abstract class AbstractAttrs<S extends AbstractSchemaTO> extends WizardSt && org.apache.cxf.common.util.CollectionUtils.isEmpty(membershipTOs.getObject())) { response.render(OnDomReadyHeaderItem.forScript( String.format("$('#emptyPlaceholder').append(\"%s\"); $('#attributes').hide();", - getString("attribute.empty.list")))); + getString("attribute.empty.list")))); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java index 9f1d3d2..9b3bce6 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java @@ -100,17 +100,17 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends AjaxWizardBuilde } if (formLayoutInfo.isAuxClasses()) { - wizardModel.add(new AuxClasses(modelObject.getInnerObject(), anyTypeClasses)); + wizardModel.add(new AuxClasses(modelObject, anyTypeClasses)); } if (formLayoutInfo.isGroups()) { - wizardModel.add(new Groups(modelObject.getInnerObject(), mode == AjaxWizard.Mode.TEMPLATE)); + wizardModel.add(new Groups(modelObject, mode == AjaxWizard.Mode.TEMPLATE)); } // attributes panel steps if (formLayoutInfo.isPlainAttrs()) { wizardModel.add(new PlainAttrs( - modelObject.getInnerObject(), + modelObject, null, mode, anyTypeClasses, @@ -118,11 +118,11 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends AjaxWizardBuilde } if (formLayoutInfo.isDerAttrs() && mode != AjaxWizard.Mode.TEMPLATE) { wizardModel.add(new DerAttrs( - modelObject.getInnerObject(), anyTypeClasses, formLayoutInfo.getWhichDerAttrs())); + modelObject, anyTypeClasses, formLayoutInfo.getWhichDerAttrs())); } if (formLayoutInfo.isVirAttrs()) { wizardModel.add(new VirAttrs( - modelObject.getInnerObject(), mode, anyTypeClasses, formLayoutInfo.getWhichVirAttrs())); + modelObject, mode, anyTypeClasses, formLayoutInfo.getWhichVirAttrs())); } // role panel step (just available for users) @@ -131,7 +131,7 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends AjaxWizardBuilde && (formLayoutInfo instanceof UserFormLayoutInfo) && UserFormLayoutInfo.class.cast(formLayoutInfo).isRoles()) { - wizardModel.add(new Roles(UserTO.class.cast(modelObject.getInnerObject()))); + wizardModel.add(new Roles(modelObject)); } // relationship panel step (available for users and any objects) @@ -140,12 +140,12 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends AjaxWizardBuilde || ((formLayoutInfo instanceof AnyObjectFormLayoutInfo) && AnyObjectFormLayoutInfo.class.cast(formLayoutInfo).isRelationships())) { - wizardModel.add(new Relationships(modelObject.getInnerObject(), pageRef)); + wizardModel.add(new Relationships(modelObject, pageRef)); } // resource panel step if (formLayoutInfo.isResources()) { - wizardModel.add(new Resources(modelObject.getInnerObject())); + wizardModel.add(new Resources(modelObject)); } return wizardModel; http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java index 5aa59aa..d0f8ac9 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/AuxClasses.java @@ -21,11 +21,15 @@ package org.apache.syncope.client.console.wizards.any; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.apache.commons.collections4.ListUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.rest.AnyTypeClassRestClient; +import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo; import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel; import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.AnyTypeClassTO; import org.apache.wicket.extensions.wizard.WizardStep; +import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.util.ListModel; @@ -33,7 +37,7 @@ public class AuxClasses extends WizardStep { private static final long serialVersionUID = 552437609667518888L; - public <T extends AnyTO> AuxClasses(final T anyTO, final List<String> anyTypeClasses) { + public <T extends AnyTO> AuxClasses(final AnyWrapper<T> modelObject, final List<String> anyTypeClasses) { super(); setOutputMarkupId(true); @@ -47,7 +51,21 @@ public class AuxClasses extends WizardStep { } Collections.sort(choices); add(new AjaxPalettePanel.Builder<String>().setAllowOrder(true).build("auxClasses", - new PropertyModel<List<String>>(anyTO, "auxClasses"), + new PropertyModel<List<String>>(modelObject.getInnerObject(), "auxClasses"), new ListModel<>(choices)).hideLabel().setOutputMarkupId(true)); + + // ------------------ + // insert changed label if needed + // ------------------ + if (modelObject instanceof UserWrapper + && UserWrapper.class.cast(modelObject).getPreviousUserTO() != null + && !ListUtils.isEqualList( + modelObject.getInnerObject().getAuxClasses(), + UserWrapper.class.cast(modelObject).getPreviousUserTO().getAuxClasses())) { + add(new LabelInfo("changed", StringUtils.EMPTY)); + } else { + add(new Label("changed", StringUtils.EMPTY)); + } + // ------------------ } } http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java index 012a662..fe6444d 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java @@ -49,11 +49,11 @@ public class DerAttrs extends AbstractAttrs<DerSchemaTO> { private static final long serialVersionUID = -5387344116983102292L; public <T extends AnyTO> DerAttrs( - final T anyTO, + final AnyWrapper<T> modelObject, final List<String> anyTypeClasses, final List<String> whichDerAttrs) { - super(anyTO, anyTypeClasses, whichDerAttrs); + super(modelObject, anyTypeClasses, whichDerAttrs); setTitleModel(new ResourceModel("attributes.derived")); add(new Accordion("derSchemas", Collections.<ITab>singletonList(new AbstractTab( http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java index 6525be5..a348f94 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Groups.java @@ -20,8 +20,10 @@ package org.apache.syncope.client.console.wizards.any; import java.util.ArrayList; import java.util.List; +import java.util.Map; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.IterableUtils; +import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.Predicate; import org.apache.commons.collections4.Transformer; import org.apache.commons.lang3.StringUtils; @@ -29,6 +31,7 @@ import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition; import org.apache.syncope.client.console.SyncopeConsoleApplication; import org.apache.syncope.client.console.rest.DynRealmRestClient; import org.apache.syncope.client.console.rest.GroupRestClient; +import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo; import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel; import org.apache.syncope.client.lib.SyncopeClient; import org.apache.syncope.common.lib.EntityTOUtils; @@ -64,11 +67,11 @@ public class Groups extends WizardStep implements ICondition { private final AnyTO anyTO; - public <T extends AnyTO> Groups(final T anyTO, final boolean templateMode) { + public <T extends AnyTO> Groups(final AnyWrapper<T> modelObject, final boolean templateMode) { super(); - this.anyTO = anyTO; - final String realm = templateMode ? "/" : anyTO.getRealm(); + this.anyTO = modelObject.getInnerObject(); + final String realm = templateMode ? "/" : this.anyTO.getRealm(); // ----------------------------------------------------------------- // Pre-Authorizations @@ -136,6 +139,33 @@ public class Groups extends WizardStep implements ICondition { // --------------------------------- // Retrieve group memberships // --------------------------------- + // this is to be sure to have group names (required to see membership details in approval page) + GroupFiqlSearchConditionBuilder searchConditionBuilder = SyncopeClient.getGroupSearchConditionBuilder(); + + List<CompleteCondition> conditions = new ArrayList<>(); + for (MembershipTO membershipTO : GroupableRelatableTO.class.cast(anyTO).getMemberships()) { + conditions.add(searchConditionBuilder.is("key").equalTo(membershipTO.getGroupKey()).wrap()); + } + + List<GroupTO> groups = new ArrayList<>(); + if (!conditions.isEmpty()) { + groups.addAll(groupRestClient.search( + "/", + searchConditionBuilder.or(conditions).query(), + -1, + -1, + new SortParam<>("name", true), + null)); + } + + // set group names in membership TOs + Map<String, MembershipTO> membershipMap = GroupableRelatableTO.class.cast(anyTO).getMembershipMap(); + for (GroupTO group : groups) { + if (membershipMap.containsKey(group.getKey())) { + membershipMap.get(group.getKey()).setGroupName(group.getName()); + } + } + groupsContainer.add(builder.setAllowOrder(true).withFilter().build("groups", new ListModel<>(GroupableRelatableTO.class.cast(anyTO).getMemberships()), new AjaxPalettePanel.Builder.Query<MembershipTO>() { @@ -150,7 +180,7 @@ public class Groups extends WizardStep implements ICondition { : groupRestClient.search( realm, SyncopeClient.getGroupSearchConditionBuilder(). - isAssignable().and().is("name").equalTo(filter).query(), + isAssignable().and().is("name").equalTo(filter).query(), 1, MAX_GROUP_LIST_CARDINALITY, new SortParam<>("name", true), null), @@ -170,16 +200,16 @@ public class Groups extends WizardStep implements ICondition { // --------------------------------- // Retrieve dyn group memberships // --------------------------------- - GroupFiqlSearchConditionBuilder searchConditionBuilder = SyncopeClient.getGroupSearchConditionBuilder(); + searchConditionBuilder = SyncopeClient.getGroupSearchConditionBuilder(); - List<CompleteCondition> conditions = new ArrayList<>(); + conditions = new ArrayList<>(); for (String groupKey : GroupableRelatableTO.class.cast(anyTO).getDynGroups()) { conditions.add(searchConditionBuilder.is("key").equalTo(groupKey).wrap()); } - List<GroupTO> dynGroups = new ArrayList<>(); + groups = new ArrayList<>(); if (!conditions.isEmpty()) { - dynGroups.addAll(groupRestClient.search( + groups.addAll(groupRestClient.search( "/", searchConditionBuilder.or(conditions).query(), -1, @@ -189,7 +219,7 @@ public class Groups extends WizardStep implements ICondition { } dyngroupsContainer.add(new AjaxPalettePanel.Builder<String>().setAllowOrder(true).build("dyngroups", - new ListModel<>(CollectionUtils.collect(dynGroups, new Transformer<GroupTO, String>() { + new ListModel<>(CollectionUtils.collect(groups, new Transformer<GroupTO, String>() { @Override public String transform(final GroupTO input) { @@ -215,6 +245,20 @@ public class Groups extends WizardStep implements ICondition { EntityTOUtils.keyTransformer(), new ArrayList<String>()))). hideLabel().setEnabled(false).setOutputMarkupId(true)); + + // ------------------ + // insert changed label if needed + // ------------------ + if (modelObject instanceof UserWrapper + && UserWrapper.class.cast(modelObject).getPreviousUserTO() != null + && !ListUtils.isEqualList( + UserWrapper.class.cast(modelObject).getInnerObject().getMemberships(), + UserWrapper.class.cast(modelObject).getPreviousUserTO().getMemberships())) { + groupsContainer.add(new LabelInfo("changed", StringUtils.EMPTY)); + } else { + groupsContainer.add(new Label("changed", StringUtils.EMPTY)); + } + // ------------------ } @Override @@ -223,6 +267,6 @@ public class Groups extends WizardStep implements ICondition { ? CollectionUtils.isNotEmpty(allDynRealms) : CollectionUtils.isNotEmpty(allDynRealms) || CollectionUtils.isNotEmpty(allGroups)) && SyncopeConsoleApplication.get().getSecuritySettings().getAuthorizationStrategy(). - isActionAuthorized(this, RENDER); + isActionAuthorized(this, RENDER); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java index 80891cf..75ca3c4 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java @@ -23,9 +23,13 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; +import org.apache.commons.collections4.ListUtils; +import org.apache.commons.collections4.Predicate; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.commons.SchemaUtils; +import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.tabs.Accordion; +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.AjaxSpinnerFieldPanel; @@ -65,16 +69,24 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> { private final AjaxWizard.Mode mode; + private final AnyTO previousObject; + public <T extends AnyTO> PlainAttrs( - final T anyTO, + final AnyWrapper<T> modelObject, final Form<?> form, final AjaxWizard.Mode mode, final List<String> anyTypeClasses, final List<String> whichPlainAttrs) throws IllegalArgumentException { - super(anyTO, anyTypeClasses, whichPlainAttrs); + super(modelObject, anyTypeClasses, whichPlainAttrs); this.mode = mode; + if (modelObject instanceof UserWrapper) { + previousObject = UserWrapper.class.cast(modelObject).getPreviousUserTO(); + } else { + previousObject = null; + } + setTitleModel(new ResourceModel("attributes.plain")); add(new Accordion("plainSchemas", Collections.<ITab>singletonList(new AbstractTab( @@ -337,17 +349,41 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> { protected void populateItem(final ListItem<AttrTO> item) { AttrTO attrTO = item.getModelObject(); - FieldPanel panel = getFieldPanel(availableSchemas.get(attrTO.getSchema())); + AbstractFieldPanel<?> panel = getFieldPanel(availableSchemas.get(attrTO.getSchema())); if (mode == AjaxWizard.Mode.TEMPLATE || !availableSchemas.get(attrTO.getSchema()).isMultivalue()) { - panel.setNewModel(attrTO.getValues()); - item.add(panel); + FieldPanel.class.cast(panel).setNewModel(attrTO.getValues()); } else { - item.add(new MultiFieldPanel.Builder<>( + panel = new MultiFieldPanel.Builder<>( new PropertyModel<List<String>>(attrTO, "values")).build( "panel", attrTO.getSchema(), - panel)); + FieldPanel.class.cast(panel)); + } + item.add(panel); + + if (previousObject != null + && (previousObject.getPlainAttr(attrTO.getSchema()) == null + || !ListUtils.isEqualList( + ListUtils.select(previousObject.getPlainAttr(attrTO.getSchema()).getValues(), + new Predicate<String>() { + + @Override + public boolean evaluate(final String object) { + return StringUtils.isNotEmpty(object); + } + }), ListUtils.select(attrTO.getValues(), + new Predicate<String>() { + + @Override + public boolean evaluate(final String object) { + return StringUtils.isNotEmpty(object); + } + })))) { + List<String> oldValues = previousObject.getPlainAttr(attrTO.getSchema()) == null + ? Collections.<String>emptyList() + : previousObject.getPlainAttr(attrTO.getSchema()).getValues(); + panel.showExternAction(new LabelInfo("externalAction", oldValues)); } } }); http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java index 0d2c323..c476251 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java @@ -28,6 +28,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.IterableUtils; import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.Predicate; +import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.commons.Constants; import org.apache.syncope.client.console.commons.SerializableTransformer; import org.apache.syncope.client.console.panels.AnyDirectoryPanel; @@ -43,6 +44,7 @@ import org.apache.syncope.client.console.rest.AnyTypeClassRestClient; import org.apache.syncope.client.console.rest.AnyTypeRestClient; import org.apache.syncope.client.console.rest.RelationshipTypeRestClient; import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; +import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.tabs.Accordion; import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink; import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType; @@ -59,16 +61,19 @@ import org.apache.syncope.common.lib.to.RelationshipTO; import org.apache.syncope.common.lib.to.RelationshipTypeTO; import org.apache.syncope.common.lib.types.AnyEntitlement; import org.apache.syncope.common.lib.types.AnyTypeKind; +import org.apache.wicket.Component; import org.apache.wicket.PageReference; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.event.Broadcast; import org.apache.wicket.event.IEvent; import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; import org.apache.wicket.extensions.markup.html.tabs.ITab; +import org.apache.wicket.extensions.wizard.IWizard; import org.apache.wicket.extensions.wizard.WizardStep; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.OnDomReadyHeaderItem; import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.IChoiceRenderer; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.markup.html.panel.Panel; @@ -89,10 +94,21 @@ public class Relationships extends WizardStep { private final AnyTO anyTO; - public Relationships(final AnyTO anyTO, final PageReference pageRef) { + public Relationships(final AnyWrapper<?> modelObject, final PageReference pageRef) { super(); - setTitleModel(new ResourceModel("any.relationships")); - this.anyTO = anyTO; + add(new Label("title", new ResourceModel("any.relationships"))); + + if (modelObject instanceof UserWrapper + && UserWrapper.class.cast(modelObject).getPreviousUserTO() != null + && !ListUtils.isEqualList( + UserWrapper.class.cast(modelObject).getInnerObject().getRelationships(), + UserWrapper.class.cast(modelObject).getPreviousUserTO().getRelationships())) { + add(new LabelInfo("changed", StringUtils.EMPTY)); + } else { + add(new Label("changed", StringUtils.EMPTY)); + } + + this.anyTO = modelObject.getInnerObject(); this.pageRef = pageRef; // ------------------------ @@ -102,6 +118,11 @@ public class Relationships extends WizardStep { // ------------------------ } + @Override + public Component getHeader(final String id, final Component parent, final IWizard wizard) { + return super.getHeader(id, parent, wizard).setVisible(false); + } + private Fragment getViewFragment() { final Map<String, List<RelationshipTO>> relationships = new HashMap<>(); addRelationship(relationships, getCurrentRelationships().toArray(new RelationshipTO[] {})); http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java index fbe729d..2ace1c7 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java @@ -22,8 +22,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.ListUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.SyncopeConsoleApplication; import org.apache.syncope.client.console.rest.ResourceRestClient; +import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo; import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel; import org.apache.syncope.common.lib.EntityTOUtils; import org.apache.syncope.common.lib.to.AnyTO; @@ -33,6 +36,7 @@ import org.apache.wicket.authroles.authorization.strategies.role.metadata.Action import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; import org.apache.wicket.extensions.wizard.WizardModel; import org.apache.wicket.extensions.wizard.WizardStep; +import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.util.ListModel; @@ -42,7 +46,19 @@ public class Resources extends WizardStep implements WizardModel.ICondition { private final ListModel<String> available; - public <T extends AnyTO> Resources(final T entityTO) { + public <T extends AnyTO> Resources(final AnyWrapper<T> modelObject) { + final T entityTO = modelObject.getInnerObject(); + + if (modelObject instanceof UserWrapper + && UserWrapper.class.cast(modelObject).getPreviousUserTO() != null + && !ListUtils.isEqualList( + modelObject.getInnerObject().getResources(), + UserWrapper.class.cast(modelObject).getPreviousUserTO().getResources())) { + add(new LabelInfo("changed", StringUtils.EMPTY)); + } else { + add(new Label("changed", StringUtils.EMPTY)); + } + // ----------------------------------------------------------------- // Pre-Authorizations // ----------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java index 6e44582..07d8275 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Roles.java @@ -22,8 +22,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.ListUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.SyncopeConsoleApplication; import org.apache.syncope.client.console.rest.RoleRestClient; +import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo; import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel; import org.apache.syncope.common.lib.EntityTOUtils; import org.apache.syncope.common.lib.to.AnyTO; @@ -34,6 +37,7 @@ import org.apache.wicket.authroles.authorization.strategies.role.metadata.Action import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; import org.apache.wicket.extensions.wizard.WizardModel.ICondition; import org.apache.wicket.extensions.wizard.WizardStep; +import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.util.ListModel; @@ -43,7 +47,22 @@ public class Roles extends WizardStep implements ICondition { private final List<String> allRoles; - public <T extends AnyTO> Roles(final UserTO entityTO) { + public <T extends AnyTO> Roles(final AnyWrapper<?> modelObject) { + if (!(modelObject.getInnerObject() instanceof UserTO)) { + throw new IllegalStateException("Invalid instance " + modelObject.getInnerObject()); + } + + if (UserWrapper.class.cast(modelObject).getPreviousUserTO() != null + && !ListUtils.isEqualList( + UserWrapper.class.cast(modelObject).getInnerObject().getRoles(), + UserWrapper.class.cast(modelObject).getPreviousUserTO().getRoles())) { + add(new LabelInfo("changed", StringUtils.EMPTY)); + } else { + add(new Label("changed", StringUtils.EMPTY)); + } + + final UserTO entityTO = UserTO.class.cast(modelObject.getInnerObject()); + // ----------------------------------------------------------------- // Pre-Authorizations // ----------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserDetails.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserDetails.java index 60e3c4d..844ff4b 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserDetails.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserDetails.java @@ -19,6 +19,8 @@ package org.apache.syncope.client.console.wizards.any; import java.util.Collections; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.tabs.Accordion; import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel; import org.apache.syncope.common.lib.to.UserTO; @@ -56,6 +58,11 @@ public class UserDetails extends Details<UserTO> { final AjaxTextFieldPanel username = new AjaxTextFieldPanel( "username", "username", new PropertyModel<String>(userTO, "username"), false); + if (wrapper.getPreviousUserTO() != null && StringUtils. + compare(wrapper.getPreviousUserTO().getUsername(), wrapper.getInnerObject().getUsername()) != 0) { + username.showExternAction(new LabelInfo("externalAction", wrapper.getPreviousUserTO().getUsername())); + } + if (templateMode) { username.enableJexlHelp(); } else { http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java index f2f1477..8d0dc5b 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java @@ -38,7 +38,7 @@ public class UserTemplateWizardBuilder extends UserWizardBuilder implements Temp final List<String> anyTypeClasses, final UserFormLayoutInfo formLayoutInfo, final PageReference pageRef) { - super(null, anyTypeClasses, formLayoutInfo, pageRef); + super(anyTypeClasses, formLayoutInfo, pageRef); this.templatable = templatable; if (templatable.getTemplates().containsKey(AnyTypeKind.USER.name())) { http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java index d2afa25..f56e24d 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java @@ -38,13 +38,38 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> implements UserF private final UserRestClient userRestClient = new UserRestClient(); + /** + * Costructor to be used for templating only. + * + * @param anyTypeClasses any type classes. + * @param formLayoutInfo form layout. + * @param pageRef reference page. + */ + public UserWizardBuilder( + final List<String> anyTypeClasses, + final UserFormLayoutInfo formLayoutInfo, + final PageReference pageRef) { + + super(new UserWrapper(null), anyTypeClasses, formLayoutInfo, pageRef); + } + + /** + * Constructor to be used for Approval details only. + * + * @param previousUserTO previous user status. + * @param userTO new user status to be approved. + * @param anyTypeClasses any type classes. + * @param formLayoutInfo from layout. + * @param pageRef reference page. + */ public UserWizardBuilder( + final UserTO previousUserTO, final UserTO userTO, final List<String> anyTypeClasses, final UserFormLayoutInfo formLayoutInfo, final PageReference pageRef) { - super(new UserWrapper(userTO), anyTypeClasses, formLayoutInfo, pageRef); + super(new UserWrapper(previousUserTO, userTO), anyTypeClasses, formLayoutInfo, pageRef); } @Override http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWrapper.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWrapper.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWrapper.java index c2a04d9..2476c63 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWrapper.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWrapper.java @@ -26,8 +26,15 @@ public class UserWrapper extends AnyWrapper<UserTO> { private boolean storePasswordInSyncope = true; + private UserTO previousUserTO; + public UserWrapper(final UserTO userTO) { + this(null, userTO); + } + + public UserWrapper(final UserTO previousUserTO, final UserTO userTO) { super(userTO); + this.previousUserTO = previousUserTO; } public boolean isStorePasswordInSyncope() { @@ -38,4 +45,7 @@ public class UserWrapper extends AnyWrapper<UserTO> { this.storePasswordInSyncope = storePasswordInSyncope; } + public UserTO getPreviousUserTO() { + return previousUserTO; + } } http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java index 4b66f0d..4ab5bee 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java @@ -22,8 +22,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.console.wicket.ajax.markup.html.LabelInfo; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.tabs.Accordion; +import org.apache.syncope.client.console.wicket.markup.html.form.AbstractFieldPanel; import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel; import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel; import org.apache.syncope.client.console.wizards.AjaxWizard; @@ -51,14 +54,17 @@ public class VirAttrs extends AbstractAttrs<VirSchemaTO> { private final AjaxWizard.Mode mode; + private final AnyWrapper<?> modelObject; + public <T extends AnyTO> VirAttrs( - final T anyTO, + final AnyWrapper<T> modelObject, final AjaxWizard.Mode mode, final List<String> anyTypeClasses, final List<String> whichVirAttrs) { - super(anyTO, anyTypeClasses, whichVirAttrs); + super(modelObject, anyTypeClasses, whichVirAttrs); this.mode = mode; + this.modelObject = modelObject; setTitleModel(new ResourceModel("attributes.virtual")); @@ -174,24 +180,34 @@ public class VirAttrs extends AbstractAttrs<VirSchemaTO> { protected void populateItem(final ListItem<AttrTO> item) { AttrTO attrTO = item.getModelObject(); - AjaxTextFieldPanel panel = - new AjaxTextFieldPanel("panel", attrTO.getSchema(), new Model<String>(), false); + AbstractFieldPanel<?> panel + = new AjaxTextFieldPanel("panel", attrTO.getSchema(), new Model<String>(), false); boolean readonly = attrTO.getSchemaInfo() == null ? false : VirSchemaTO.class.cast(attrTO.getSchemaInfo()).isReadonly(); if (mode == AjaxWizard.Mode.TEMPLATE) { - item.add(panel.enableJexlHelp().setEnabled(!readonly)); + AjaxTextFieldPanel.class.cast(panel).enableJexlHelp().setEnabled(!readonly); } else { - item.add(new MultiFieldPanel.Builder<>( + panel = new MultiFieldPanel.Builder<>( new PropertyModel<List<String>>(attrTO, "values")).build( "panel", attrTO.getSchema(), - panel).setEnabled(!readonly)); + AjaxTextFieldPanel.class.cast(panel)); + panel.setEnabled(!readonly); + } + + item.add(panel); + + if (CollectionUtils.isNotEmpty(attrTO.getValues()) + && VirAttrs.this.modelObject instanceof UserWrapper + && UserWrapper.class.cast(VirAttrs.this.modelObject).getPreviousUserTO() != null) { + panel.showExternAction(new LabelInfo("externalAction", StringUtils.EMPTY)); } } - }); + } + ); } } } http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AuxClasses.html ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AuxClasses.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AuxClasses.html index 851d51b..f70fdfe 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AuxClasses.html +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/AuxClasses.html @@ -24,6 +24,7 @@ under the License. <h3 class="box-title"> <wicket:message key="auxClasses.palette">AUX CLASSES</wicket:message> </h3> + <span wicket:id="changed"></span> </div> <div class="box-body"> <span wicket:id="auxClasses">[AUX CLASSES]</span> http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Groups.html ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Groups.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Groups.html index 3a5b769..10b6524 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Groups.html +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Groups.html @@ -24,6 +24,7 @@ under the License. <h3 class="box-title"> <wicket:message key="groups.palette">[GROUPS]</wicket:message> </h3> + <span wicket:id="changed"></span> </div> <div class="box-body"> <span wicket:id="groups"/> http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.html ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.html index 34e8266..bfa6f45 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.html +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.html @@ -20,6 +20,10 @@ under the License. <head><title></title></head> <body> <wicket:panel> + <div class="wizard-step-title"> + <div><span wicket:id="title">[RELATIONSHIPS]</span></div><span wicket:id="changed"></span> + </div> + <div id="emptyPlaceholder"/> <span wicket:id="relationships"/> http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Resources.html ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Resources.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Resources.html index ae54159..54219d1 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Resources.html +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Resources.html @@ -26,6 +26,7 @@ under the License. <h3 class="box-title"> <wicket:message key="resources.palette">[ROLES]</wicket:message> </h3> + <span wicket:id="changed"></span> </div> <div class="box-body"> <span wicket:id="resources">[RESOURCES]</span> http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html index 65c8b50..f7eded7 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Roles.html @@ -26,13 +26,14 @@ under the License. <h3 class="box-title"> <wicket:message key="roles.palette">[ROLES]</wicket:message> </h3> + <span wicket:id="changed"></span> </div> <div class="box-body"> <span wicket:id="roles">[ROLES]</span> </div> </div> </div> - + <div class="col-xs-12"> <div class="box"> <div class="box-header"> http://git-wip-us.apache.org/repos/asf/syncope/blob/78b68bf4/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java b/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java index 69d373e..0008842 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java @@ -438,17 +438,6 @@ public final class AnyOperations { if (patch.getOperation() == PatchOperation.ADD_REPLACE) { rwattrs.put(patch.getAttrTO().getSchema(), patch.getAttrTO()); } - switch (patch.getOperation()) { - case ADD_REPLACE: - if (rwattrs.containsKey(patch.getAttrTO().getSchema())) { - rwattrs.remove(patch.getAttrTO().getSchema()); - } - break; - - case DELETE: - default: - rwattrs.remove(patch.getAttrTO().getSchema()); - } } } @@ -472,12 +461,12 @@ public final class AnyOperations { for (StringPatchItem auxClassPatch : patch.getAuxClasses()) { switch (auxClassPatch.getOperation()) { case ADD_REPLACE: - to.getAuxClasses().add(auxClassPatch.getValue()); + result.getAuxClasses().add(auxClassPatch.getValue()); break; case DELETE: default: - to.getAuxClasses().remove(auxClassPatch.getValue()); + result.getAuxClasses().remove(auxClassPatch.getValue()); } }