| /* |
| * 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.wizards.any; |
| |
| import org.apache.syncope.client.ui.commons.wizards.any.EntityWrapper; |
| import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggle; |
| import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.stream.Collectors; |
| import org.apache.syncope.client.console.rest.AnyTypeRestClient; |
| import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel; |
| import org.apache.syncope.common.lib.EntityTOUtils; |
| import org.apache.syncope.common.lib.to.AnyTO; |
| import org.apache.syncope.common.lib.to.LinkedAccountTO; |
| import org.apache.syncope.common.lib.to.PlainSchemaTO; |
| import org.apache.syncope.common.lib.to.UserTO; |
| import org.apache.syncope.client.console.commons.LinkedAccountPlainAttrProperty; |
| import org.apache.syncope.client.ui.commons.Constants; |
| import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; |
| import org.apache.syncope.client.ui.commons.markup.html.form.AbstractFieldPanel; |
| import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel; |
| import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion; |
| import org.apache.syncope.client.ui.commons.wizards.AjaxWizard; |
| import org.apache.syncope.common.lib.Attr; |
| import org.apache.syncope.common.lib.types.SchemaType; |
| import org.apache.wicket.ajax.AjaxRequestTarget; |
| import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; |
| import org.apache.wicket.markup.ComponentTag; |
| import org.apache.wicket.markup.html.WebMarkupContainer; |
| import org.apache.wicket.markup.html.form.CheckBox; |
| import org.apache.wicket.markup.html.form.FormComponent; |
| import org.apache.wicket.markup.html.list.ListItem; |
| import org.apache.wicket.markup.html.list.ListView; |
| import org.apache.wicket.model.IModel; |
| import org.apache.wicket.model.Model; |
| import org.apache.wicket.model.PropertyModel; |
| import org.apache.wicket.model.ResourceModel; |
| |
| public class LinkedAccountPlainAttrsPanel extends AbstractAttrsWizardStep<PlainSchemaTO> { |
| |
| private static final long serialVersionUID = -6664931684253730934L; |
| |
| private final LinkedAccountTO linkedAccountTO; |
| |
| private final UserTO userTO; |
| |
| private final Set<Attr> fixedAttrs = new HashSet<>(); |
| |
| private final List<LinkedAccountPlainAttrProperty> accountPlainAttrProperties = new ArrayList<>(); |
| |
| public <T extends AnyTO> LinkedAccountPlainAttrsPanel( |
| final EntityWrapper<LinkedAccountTO> modelObject, |
| final UserTO userTO, |
| final List<String> whichPlainAttrs) throws IllegalArgumentException { |
| |
| super(userTO, |
| AjaxWizard.Mode.EDIT, |
| AnyTypeRestClient.read(userTO.getType()).getClasses(), |
| whichPlainAttrs); |
| |
| this.linkedAccountTO = modelObject.getInnerObject(); |
| this.fixedAttrs.addAll(this.linkedAccountTO.getPlainAttrs().stream(). |
| filter(attrTO -> checkIsReadonlyAttr(attrTO.getSchema())). |
| collect(Collectors.toList())); |
| this.userTO = userTO; |
| |
| add(new Accordion("plainSchemas", List.of(new AbstractTab( |
| new ResourceModel("attributes.accordion", "Plain Attributes")) { |
| |
| private static final long serialVersionUID = -7078941093668723016L; |
| |
| @Override |
| public WebMarkupContainer getPanel(final String panelId) { |
| return new PlainSchemasOwn(panelId, schemas, attrs); |
| } |
| }), Model.of(0)).setOutputMarkupId(true)); |
| } |
| |
| @Override |
| protected FormComponent<?> checkboxToggle( |
| final Attr attrTO, |
| final AbstractFieldPanel<?> panel, |
| final boolean isMultivalue) { |
| |
| LinkedAccountPlainAttrProperty property = accountPlainAttrProperties.stream().filter( |
| existingProperty -> { |
| return existingProperty.getSchema().equals(attrTO.getSchema()); |
| }).findFirst().orElseGet(() -> { |
| LinkedAccountPlainAttrProperty newProperty = new LinkedAccountPlainAttrProperty(); |
| newProperty.setOverridable(linkedAccountTO.getPlainAttr(attrTO.getSchema()).isPresent()); |
| newProperty.setSchema(attrTO.getSchema()); |
| newProperty.getValues().addAll(attrTO.getValues()); |
| accountPlainAttrProperties.add(newProperty); |
| return newProperty; |
| }); |
| |
| final BootstrapToggleConfig config = new BootstrapToggleConfig(). |
| withOnStyle(BootstrapToggleConfig.Style.success). |
| withOffStyle(BootstrapToggleConfig.Style.danger). |
| withSize(BootstrapToggleConfig.Size.mini); |
| |
| return new BootstrapToggle("externalAction", new PropertyModel<>(property, "overridable"), config) { |
| |
| private static final long serialVersionUID = -875219845189261873L; |
| |
| @Override |
| protected CheckBox newCheckBox(final String id, final IModel<Boolean> model) { |
| final CheckBox checkBox = super.newCheckBox(id, model); |
| checkBox.add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { |
| |
| private static final long serialVersionUID = -1107858522700306810L; |
| |
| @Override |
| protected void onUpdate(final AjaxRequestTarget target) { |
| if (isMultivalue) { |
| MultiFieldPanel.class.cast(panel).setFormReadOnly(!model.getObject()); |
| } else { |
| FieldPanel.class.cast(panel).setReadOnly(!model.getObject()); |
| } |
| |
| updateAccountPlainSchemas(property, model.getObject()); |
| target.add(panel); |
| } |
| }); |
| return checkBox; |
| } |
| |
| @Override |
| protected IModel<String> getOnLabel() { |
| return Model.of("Override"); |
| } |
| |
| @Override |
| protected IModel<String> getOffLabel() { |
| return Model.of("Override?"); |
| } |
| |
| @Override |
| protected void onComponentTag(final ComponentTag tag) { |
| super.onComponentTag(tag); |
| tag.append("class", "overridable", " "); |
| } |
| }; |
| } |
| |
| private void updateAccountPlainSchemas(final LinkedAccountPlainAttrProperty property, final Boolean modelObject) { |
| Set<Attr> withoutCurrentSchema = new HashSet<>(linkedAccountTO.getPlainAttrs().stream(). |
| filter(attrTO -> !attrTO.getSchema().equals(property.getSchema()) |
| && checkIsReadonlyAttr(attrTO.getSchema())). |
| collect(Collectors.toSet())); |
| linkedAccountTO.getPlainAttrs().clear(); |
| linkedAccountTO.getPlainAttrs().addAll(withoutCurrentSchema); |
| if (modelObject) { |
| linkedAccountTO.getPlainAttrs().add( |
| fixedAttrs.stream().filter(attrTO -> attrTO.getSchema().equals(property.getSchema())).findFirst(). |
| orElseGet(() -> new Attr.Builder(property.getSchema()). |
| values(property.getValues()).build())); |
| } |
| } |
| |
| @Override |
| protected SchemaType getSchemaType() { |
| return SchemaType.PLAIN; |
| } |
| |
| @Override |
| protected void setAttrs() { |
| List<Attr> attrs = new ArrayList<>(); |
| List<PlainSchemaTO> notReadonlyValues = schemas.values().stream(). |
| filter(schema -> checkIsReadonlyAttr(schema.getKey())). |
| collect(Collectors.toList()); |
| setFixedAttr(notReadonlyValues); |
| Map<String, Attr> attrMap = EntityTOUtils.buildAttrMap(fixedAttrs); |
| |
| attrs.addAll(notReadonlyValues.stream(). |
| map(schema -> { |
| Attr attrTO = new Attr(); |
| attrTO.setSchema(schema.getKey()); |
| if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) { |
| attrTO.getValues().add(""); |
| } else { |
| attrTO = attrMap.get(schema.getKey()); |
| } |
| return attrTO; |
| }). |
| collect(Collectors.toList())); |
| |
| fixedAttrs.clear(); |
| fixedAttrs.addAll(attrs); |
| } |
| |
| @Override |
| protected List<Attr> getAttrsFromTO() { |
| return fixedAttrs.stream().sorted(attrComparator).collect(Collectors.toList()); |
| } |
| |
| private void setFixedAttr(final Collection<PlainSchemaTO> values) { |
| values.forEach(schema -> { |
| if (linkedAccountTO.getPlainAttr(schema.getKey()).isPresent()) { |
| fixedAttrs.add(linkedAccountTO.getPlainAttr(schema.getKey()).get()); |
| } else if (userTO.getPlainAttr(schema.getKey()).isPresent()) { |
| fixedAttrs.add(userTO.getPlainAttr(schema.getKey()).get()); |
| } |
| }); |
| } |
| |
| private boolean checkIsReadonlyAttr(final String schema) { |
| return schemas.isEmpty() ? true : !schemas.get(schema).isReadonly(); |
| } |
| |
| private class PlainSchemasOwn extends PlainSchemas<List<Attr>> { |
| |
| private static final long serialVersionUID = -4730563859116024676L; |
| |
| PlainSchemasOwn( |
| final String id, |
| final Map<String, PlainSchemaTO> schemas, |
| final IModel<List<Attr>> attrTOs) { |
| |
| super(id); |
| |
| add(new ListView<>("schemas", attrTOs) { |
| |
| private static final long serialVersionUID = 9101744072914090143L; |
| |
| @Override |
| protected void populateItem(final ListItem<Attr> item) { |
| Attr attrTO = item.getModelObject(); |
| final boolean isMultivalue = schemas.get(attrTO.getSchema()).isMultivalue(); |
| |
| AbstractFieldPanel<?> panel = setPanel( |
| schemas, |
| item, |
| linkedAccountTO.getPlainAttr(attrTO.getSchema()).isEmpty()); |
| |
| panel.showExternAction(checkboxToggle(attrTO, panel, isMultivalue)); |
| } |
| }); |
| } |
| } |
| } |