/* * 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 de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal; import java.io.Serializable; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.commons.AnyDataProvider; import org.apache.syncope.client.console.commons.Constants; import org.apache.syncope.client.console.commons.SerializableTransformer; import org.apache.syncope.client.console.commons.status.ConnObjectWrapper; import org.apache.syncope.client.console.commons.status.StatusBean; import org.apache.syncope.client.console.rest.AbstractAnyRestClient; import org.apache.syncope.client.console.rest.SchemaRestClient; import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BooleanPropertyColumn; import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn; import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.KeyPropertyColumn; import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.TokenColumn; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal; import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink; import org.apache.syncope.client.console.wizards.any.AnyWrapper; import org.apache.syncope.client.console.wizards.any.StatusPanel; import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.AnyTypeClassTO; import org.apache.syncope.common.lib.to.ConnObjectTO; import org.apache.syncope.common.lib.to.PropagationStatus; import org.apache.syncope.common.lib.to.ProvisioningResult; import org.apache.wicket.PageReference; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.model.util.ListModel; public abstract class AnyDirectoryPanel<A extends AnyTO, E extends AbstractAnyRestClient<A, ?>> extends DirectoryPanel<A, AnyWrapper<A>, AnyDataProvider<A>, E> { private static final long serialVersionUID = -1100228004207271270L; protected final SchemaRestClient schemaRestClient = new SchemaRestClient(); protected final List<String> pSchemaNames; protected final List<String> dSchemaNames; /** * Filter used in case of filtered search. */ protected String fiql; /** * Realm related to current panel. */ protected final String realm; /** * Any type related to current panel. */ protected final String type; protected final BaseModal<Serializable> utilityModal = new BaseModal<>("outer"); protected AnyDirectoryPanel(final String id, final Builder<A, E> builder) { this(id, builder, true); } protected AnyDirectoryPanel(final String id, final Builder<A, E> builder, final boolean wizardInModal) { super(id, builder, wizardInModal); if (SyncopeConsoleSession.get().owns(String.format("%s_CREATE", builder.type), builder.realm)) { MetaDataRoleAuthorizationStrategy.authorizeAll(addAjaxLink, RENDER); } else { MetaDataRoleAuthorizationStrategy.unauthorizeAll(addAjaxLink, RENDER); } setReadOnly(!SyncopeConsoleSession.get().owns(String.format("%s_UPDATE", builder.type), builder.realm)); this.realm = builder.realm; this.type = builder.type; this.fiql = builder.fiql; utilityModal.size(Modal.Size.Large); addOuterObject(utilityModal); setWindowClosedReloadCallback(utilityModal); modal.size(Modal.Size.Large); altDefaultModal.size(Modal.Size.Large); this.pSchemaNames = new ArrayList<>(); for (AnyTypeClassTO anyTypeClassTO : AnyDirectoryPanelBuilder.class.cast(builder).getAnyTypeClassTOs()) { this.pSchemaNames.addAll(anyTypeClassTO.getPlainSchemas()); } this.dSchemaNames = new ArrayList<>(); for (AnyTypeClassTO anyTypeClassTO : AnyDirectoryPanelBuilder.class.cast(builder).getAnyTypeClassTOs()) { this.dSchemaNames.addAll(anyTypeClassTO.getDerSchemas()); } initResultTable(); } protected void addPropertyColumn( final String name, final Field field, final List<IColumn<A, String>> columns) { if (Constants.KEY_FIELD_NAME.equalsIgnoreCase(name)) { columns.add(new KeyPropertyColumn<A>(new ResourceModel(name, name), name, name)); } else if (Constants.DEFAULT_TOKEN_FIELD_NAME.equalsIgnoreCase(name)) { columns.add(new TokenColumn<A>(new ResourceModel(name, name), name)); } else if (field != null && (field.getType().equals(Boolean.class) || field.getType().equals(boolean.class))) { columns.add(new BooleanPropertyColumn<A>(new ResourceModel(name, name), name, name)); } else if (field != null && field.getType().equals(Date.class)) { columns.add(new DatePropertyColumn<A>(new ResourceModel(name, name), name, name)); } else { columns.add(new PropertyColumn<A, String>(new ResourceModel(name, name), name, name)); } } @Override protected AnyDataProvider<A> dataProvider() { final AnyDataProvider<A> dp = new AnyDataProvider<>(restClient, rows, filtered, realm, type); return dp.setFIQL(this.fiql); } public void search(final String fiql, final AjaxRequestTarget target) { this.fiql = fiql; dataProvider.setFIQL(fiql); super.search(target); } @Override protected Collection<ActionLink.ActionType> getBulkActions() { List<ActionLink.ActionType> bulkActions = new ArrayList<>(); bulkActions.add(ActionLink.ActionType.DELETE); return bulkActions; } public interface AnyDirectoryPanelBuilder extends Serializable { List<AnyTypeClassTO> getAnyTypeClassTOs(); } public abstract static class Builder<A extends AnyTO, E extends AbstractAnyRestClient<A, ?>> extends DirectoryPanel.Builder<A, AnyWrapper<A>, E> implements AnyDirectoryPanelBuilder { private static final long serialVersionUID = -6828423611982275640L; /** * Realm related to current panel. */ protected String realm = "/"; /** * Any type related to current panel. */ protected final String type; private final List<AnyTypeClassTO> anyTypeClassTOs; public Builder( final List<AnyTypeClassTO> anyTypeClassTOs, final E restClient, final String type, final PageReference pageRef) { super(restClient, pageRef); this.anyTypeClassTOs = anyTypeClassTOs; this.type = type; } public Builder<A, E> setRealm(final String realm) { this.realm = realm; return this; } @Override public List<AnyTypeClassTO> getAnyTypeClassTOs() { return this.anyTypeClassTOs; } } @Override @SuppressWarnings("unchecked") protected Panel customResultBody(final String panelId, final AnyWrapper<A> item, final Serializable result) { if (!(result instanceof ProvisioningResult)) { throw new IllegalStateException("Unsupported result type"); } return new StatusPanel( panelId, ((ProvisioningResult<A>) result).getEntity(), new ListModel<>(new ArrayList<StatusBean>()), CollectionUtils.collect( ((ProvisioningResult<A>) result).getPropagationStatuses(), new SerializableTransformer<PropagationStatus, Pair<ConnObjectTO, ConnObjectWrapper>>() { private static final long serialVersionUID = -4931455531906427515L; @Override public Pair<ConnObjectTO, ConnObjectWrapper> transform(final PropagationStatus input) { ConnObjectTO before = input.getBeforeObj(); ConnObjectWrapper afterObjWrapper = new ConnObjectWrapper( ((ProvisioningResult<A>) result).getEntity(), input.getResource(), input.getAfterObj()); return Pair.of(before, afterObjWrapper); } }, new ArrayList<Pair<ConnObjectTO, ConnObjectWrapper>>()), pageRef); } }