blob: 3b160788d45fe560377955c194e3ef26d1bcd0a5 [file] [log] [blame]
/*
* 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()).isPresent());
panel.showExternAction(checkboxToggle(attrTO, panel, isMultivalue));
}
});
}
}
}