Package org.apache.syncope.console.pages.panels

Source Code of org.apache.syncope.console.pages.panels.ResourceMappingPanel

/*
* 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.console.pages.panels;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.syncope.common.to.ConnInstanceTO;
import org.apache.syncope.common.to.MappingItemTO;
import org.apache.syncope.common.to.MappingTO;
import org.apache.syncope.common.to.ResourceTO;
import org.apache.syncope.common.types.AttributableType;
import org.apache.syncope.common.types.ConnConfProperty;
import org.apache.syncope.common.types.IntMappingType;
import org.apache.syncope.common.types.MappingPurpose;
import org.apache.syncope.console.commons.JexlHelpUtil;
import org.apache.syncope.console.pages.panels.ResourceConnConfPanel.ConnConfModEvent;
import org.apache.syncope.console.rest.ConnectorRestClient;
import org.apache.syncope.console.rest.SchemaRestClient;
import org.apache.syncope.console.wicket.markup.html.form.AjaxCheckBoxPanel;
import org.apache.syncope.console.wicket.markup.html.form.AjaxDecoratedCheckbox;
import org.apache.syncope.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
import org.apache.syncope.console.wicket.markup.html.form.AjaxTextFieldPanel;
import org.apache.syncope.console.wicket.markup.html.form.FieldPanel;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.attributes.AjaxCallListener;
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
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.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Resource mapping panel.
*/
public class ResourceMappingPanel extends Panel {

    private static final long serialVersionUID = -7982691107029848579L;

    /**
     * Logger.
     */
    private static final Logger LOG = LoggerFactory.getLogger(ResourceMappingPanel.class);

    /**
     * OnChange event name.
     */
    private static final String ON_CHANGE = "onchange";

    /**
     * Mapping field style sheet.
     */
    private static final String FIELD_STYLE = "ui-widget-content ui-corner-all short_fixedsize";

    /**
     * Mapping field style sheet.
     */
    private static final String DEF_FIELD_STYLE = "ui-widget-content ui-corner-all";

    /**
     * Mapping field style sheet.
     */
    private static final String SHORT_FIELD_STYLE = "ui-widget-content ui-corner-all veryshort_fixedsize";

    /**
     * Schema rest client.
     */
    @SpringBean
    private SchemaRestClient schemaRestClient;

    /**
     * ConnInstance rest client.
     */
    @SpringBean
    private ConnectorRestClient connRestClient;

    /**
     * Resource schema name.
     */
    private final List<String> schemaNames;

    /**
     * Add mapping button.
     */
    private final AjaxButton addMappingBtn;

    /**
     * All mappings.
     */
    private final ListView<MappingItemTO> mappings;

    /**
     * External resource to be updated.
     */
    private final ResourceTO resourceTO;

    /**
     * User / role.
     */
    private final AttributableType attrType;

    /**
     * Mapping container.
     */
    private final WebMarkupContainer mappingContainer;

    /**
     * AccountLink container.
     */
    private final WebMarkupContainer accountLinkContainer;

    private MappingTO getMapping() {
        MappingTO result = null;

        if (AttributableType.USER == attrType) {
            if (this.resourceTO.getUmapping() == null) {
                this.resourceTO.setUmapping(new MappingTO());
            }
            result = this.resourceTO.getUmapping();
        }
        if (AttributableType.ROLE == attrType) {
            if (this.resourceTO.getRmapping() == null) {
                this.resourceTO.setRmapping(new MappingTO());
            }
            result = this.resourceTO.getRmapping();
        }

        return result;
    }

    /**
     * Attribute Mapping Panel.
     *
     * @param id panel id
     * @param resourceTO external resource
     * @param attrType USER / ROLE
     */
    public ResourceMappingPanel(final String id, final ResourceTO resourceTO, final AttributableType attrType) {
        super(id);
        setOutputMarkupId(true);

        this.resourceTO = resourceTO;
        this.attrType = attrType;

        if (this.resourceTO.getConnectorId() != null && this.resourceTO.getConnectorId() > 0) {
            schemaNames =
                    getResourceSchemaNames(this.resourceTO.getConnectorId(), this.resourceTO.getConnConfProperties());
        } else {
            schemaNames = Collections.<String>emptyList();
        }

        accountLinkContainer = new WebMarkupContainer("accountLinkContainer");
        accountLinkContainer.setOutputMarkupId(true);
        add(accountLinkContainer);

        boolean accountLinkEnabled = false;
        if (getMapping().getAccountLink() != null) {
            accountLinkEnabled = true;
        }
        final AjaxCheckBoxPanel accountLinkCheckbox = new AjaxCheckBoxPanel("accountLinkCheckbox",
                new ResourceModel("accountLinkCheckbox", "accountLinkCheckbox").getObject(),
                new Model<Boolean>(Boolean.valueOf(accountLinkEnabled)));
        accountLinkCheckbox.setEnabled(true);

        accountLinkContainer.add(accountLinkCheckbox);

        final AjaxTextFieldPanel accountLink = new AjaxTextFieldPanel("accountLink",
                new ResourceModel("accountLink", "accountLink").getObject(),
                new PropertyModel<String>(getMapping(), "accountLink"));
        accountLink.setEnabled(accountLinkEnabled);
        accountLinkContainer.add(accountLink);

        accountLinkCheckbox.getField().add(new AjaxFormComponentUpdatingBehavior(ON_CHANGE) {

            private static final long serialVersionUID = -1107858522700306810L;

            @Override
            protected void onUpdate(final AjaxRequestTarget target) {
                if (accountLinkCheckbox.getModelObject()) {
                    accountLink.setEnabled(Boolean.TRUE);
                    accountLink.setModelObject("");
                } else {
                    accountLink.setEnabled(Boolean.FALSE);
                    accountLink.setModelObject("");
                }

                target.add(accountLink);
            }
        });

        mappingContainer = new WebMarkupContainer("mappingContainer");
        mappingContainer.setOutputMarkupId(true);

        final WebMarkupContainer jexlHelp = JexlHelpUtil.getJexlHelpWebContainer("jexlHelp");
        mappingContainer.add(jexlHelp);

        AjaxLink<Void> questionMarkJexlHelp = JexlHelpUtil.getAjaxLink(jexlHelp, "questionMarkJexlHelp");
        mappingContainer.add(questionMarkJexlHelp);

        add(mappingContainer);

        final Label passwordLabel = new Label("passwordLabel", new ResourceModel("password"));
        mappingContainer.add(passwordLabel);
        if (AttributableType.USER != ResourceMappingPanel.this.attrType) {
            passwordLabel.setVisible(false);
        }

        Collections.sort(getMapping().getItems(), new Comparator<MappingItemTO>() {

            @Override
            public int compare(final MappingItemTO left, final MappingItemTO right) {
                if (left == null && right == null) {
                    return 0;
                } else if (left == null) {
                    return 1;
                } else if (right == null) {
                    return -1;
                } else if (left.getPurpose() == MappingPurpose.BOTH && right.getPurpose() != MappingPurpose.BOTH) {
                    return -1;
                } else if (left.getPurpose() != MappingPurpose.BOTH && right.getPurpose() == MappingPurpose.BOTH) {
                    return 1;
                } else if (left.getPurpose() == MappingPurpose.PROPAGATION
                        && right.getPurpose() == MappingPurpose.SYNCHRONIZATION) {
                    return -1;
                } else if (left.getPurpose() == MappingPurpose.SYNCHRONIZATION
                        && right.getPurpose() == MappingPurpose.PROPAGATION) {
                    return 1;
                } else if (left.isAccountid()) {
                    return -1;
                } else if (right.isAccountid()) {
                    return 1;
                } else if (left.isPassword()) {
                    return -1;
                } else if (right.isPassword()) {
                    return 1;
                } else {
                    return left.getIntAttrName().compareTo(right.getIntAttrName());
                }
            }
        });


        mappings = new ListView<MappingItemTO>("mappings", getMapping().getItems()) {

            private static final long serialVersionUID = 4949588177564901031L;

            @Override
            protected void populateItem(final ListItem<MappingItemTO> item) {
                final MappingItemTO mapItem = item.getModelObject();
                if (mapItem.getPurpose() == null) {
                    mapItem.setPurpose(MappingPurpose.BOTH);
                }

                AttributableType entity = null;
                if (mapItem.getIntMappingType() != null) {
                    entity = mapItem.getIntMappingType().getAttributableType();
                }

                final List<IntMappingType> attrTypes = new ArrayList<IntMappingType>(getAttributeTypes(entity));

                item.add(new AjaxDecoratedCheckbox("toRemove", new Model<Boolean>(Boolean.FALSE)) {

                    private static final long serialVersionUID = 7170946748485726506L;

                    @Override
                    protected void onUpdate(final AjaxRequestTarget target) {
                        int index = -1;
                        for (int i = 0; i < getMapping().getItems().size() && index == -1; i++) {
                            if (mapItem.equals(getMapping().getItems().get(i))) {
                                index = i;
                            }
                        }

                        if (index != -1) {
                            getMapping().getItems().remove(index);
                            item.getParent().removeAll();
                            target.add(ResourceMappingPanel.this);
                        }
                    }

                    @Override
                    protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
                        super.updateAjaxAttributes(attributes);

                        final AjaxCallListener ajaxCallListener = new AjaxCallListener() {

                            private static final long serialVersionUID = 7160235486520935153L;

                            @Override
                            public CharSequence getPrecondition(final Component component) {
                                return "if (!confirm('" + getString("confirmDelete") + "')) return false;";
                            }
                        };
                        attributes.getAjaxCallListeners().add(ajaxCallListener);
                    }
                });

                final AjaxDropDownChoicePanel<String> intAttrNames =
                        new AjaxDropDownChoicePanel<String>("intAttrNames", getString("intAttrNames"),
                        new PropertyModel<String>(mapItem, "intAttrName"), false);
                intAttrNames.setChoices(schemaNames);
                intAttrNames.setRequired(true);
                intAttrNames.setStyleSheet(FIELD_STYLE);
                intAttrNames.getField().add(new AjaxFormComponentUpdatingBehavior(ON_CHANGE) {

                    private static final long serialVersionUID = -1107858522700306810L;

                    @Override
                    protected void onUpdate(final AjaxRequestTarget target) {
                    }
                });
                item.add(intAttrNames);

                final AjaxDropDownChoicePanel<IntMappingType> intMappingTypes =
                        new AjaxDropDownChoicePanel<IntMappingType>("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<AttributableType> entitiesPanel =
                        new AjaxDropDownChoicePanel<AttributableType>("entities",
                        new ResourceModel("entities", "entities").getObject(), new Model<AttributableType>(entity));
                entitiesPanel.setChoices(attrType == AttributableType.ROLE
                        ? Collections.<AttributableType>singletonList(AttributableType.ROLE)
                        : Arrays.asList(AttributableType.values()));
                entitiesPanel.setStyleSheet(DEF_FIELD_STYLE);
                entitiesPanel.getField().add(new AjaxFormComponentUpdatingBehavior(ON_CHANGE) {

                    private static final long serialVersionUID = -1107858522700306810L;

                    @Override
                    protected void onUpdate(final AjaxRequestTarget target) {
                        attrTypes.clear();
                        attrTypes.addAll(getAttributeTypes(entitiesPanel.getModelObject()));
                        intMappingTypes.setChoices(attrTypes);

                        intAttrNames.setChoices(Collections.<String>emptyList());

                        target.add(intMappingTypes.getField());
                        target.add(intAttrNames.getField());
                    }
                });
                item.add(entitiesPanel);

                final FieldPanel extAttrNames = new AjaxTextFieldPanel("extAttrName",
                        new ResourceModel("extAttrNames", "extAttrNames").getObject(),
                        new PropertyModel<String>(mapItem, "extAttrName"));
                ((AjaxTextFieldPanel) extAttrNames).setChoices(schemaNames);

                boolean required = false;
                boolean accountIdOrPassword = mapItem.isAccountid() || mapItem.isPassword();
                if (accountIdOrPassword) {
                    ((AjaxTextFieldPanel) extAttrNames).setModelObject(null);
                } else if (!schemaNames.isEmpty()) {
                    required = true;
                }
                extAttrNames.setRequired(required);
                extAttrNames.setEnabled(required);
                extAttrNames.setStyleSheet(FIELD_STYLE);
                item.add(extAttrNames);

                final AjaxTextFieldPanel mandatory = new AjaxTextFieldPanel("mandatoryCondition",
                        new ResourceModel("mandatoryCondition", "mandatoryCondition").getObject(),
                        new PropertyModel<String>(mapItem, "mandatoryCondition"));
                mandatory.setChoices(Arrays.asList(new String[] {"true", "false"}));
                mandatory.setStyleSheet(SHORT_FIELD_STYLE);
                item.add(mandatory);

                final AjaxCheckBoxPanel accountId = new AjaxCheckBoxPanel("accountId",
                        new ResourceModel("accountId", "accountId").getObject(),
                        new PropertyModel<Boolean>(mapItem, "accountid"));
                accountId.getField().add(new AjaxFormComponentUpdatingBehavior(ON_CHANGE) {

                    private static final long serialVersionUID = -1107858522700306810L;

                    @Override
                    protected void onUpdate(final AjaxRequestTarget target) {
                        extAttrNames.setEnabled(!accountId.getModelObject() && !mapItem.isPassword());
                        extAttrNames.setModelObject(null);
                        extAttrNames.setRequired(!accountId.getModelObject());
                        target.add(extAttrNames);

                        if (accountId.getModelObject()) {
                            mapItem.setMandatoryCondition("true");
                            mandatory.setEnabled(false);
                        } else {
                            mapItem.setMandatoryCondition("false");
                            mandatory.setEnabled(true);
                        }
                        target.add(mandatory);
                    }
                });
                item.add(accountId);

                final AjaxCheckBoxPanel password = new AjaxCheckBoxPanel("password",
                        new ResourceModel("password", "password").getObject(),
                        new PropertyModel<Boolean>(mapItem, "password"));
                password.getField().add(new AjaxFormComponentUpdatingBehavior(ON_CHANGE) {

                    private static final long serialVersionUID = -1107858522700306810L;

                    @Override
                    protected void onUpdate(final AjaxRequestTarget target) {
                        extAttrNames.setEnabled(!mapItem.isAccountid() && !password.getModelObject());
                        extAttrNames.setModelObject(null);
                        extAttrNames.setRequired(!password.getModelObject());
                        target.add(extAttrNames);

                        setAccountId(intMappingTypes.getModelObject(), accountId, password);
                        target.add(accountId);
                    }
                });
                item.add(password);
                if (AttributableType.USER != ResourceMappingPanel.this.attrType) {
                    password.setVisible(false);
                }

                final AjaxDropDownChoicePanel<MappingPurpose> purpose =
                        new AjaxDropDownChoicePanel<MappingPurpose>("purpose",
                        new ResourceModel("purpose", "purpose").getObject(),
                        new PropertyModel<MappingPurpose>(mapItem, "purpose"),
                        false);
                purpose.setChoices(Arrays.asList(MappingPurpose.values()));
                purpose.setStyleSheet(FIELD_STYLE);
                purpose.setRequired(true);
                purpose.getField().add(new AjaxFormComponentUpdatingBehavior(ON_CHANGE) {

                    private static final long serialVersionUID = -1107858522700306810L;

                    @Override
                    protected void onUpdate(final AjaxRequestTarget target) {
                    }
                });

                item.add(purpose);

                intMappingTypes.getField().add(new AjaxFormComponentUpdatingBehavior(ON_CHANGE) {

                    private static final long serialVersionUID = -1107858522700306810L;

                    @Override
                    protected void onUpdate(final AjaxRequestTarget target) {
                        setAttrNames(intMappingTypes.getModelObject(), intAttrNames);
                        target.add(intAttrNames);

                        setAccountId(intMappingTypes.getModelObject(), accountId, password);
                        target.add(accountId);
                    }
                });

                setAttrNames(mapItem.getIntMappingType(), intAttrNames);
                setAccountId(mapItem.getIntMappingType(), accountId, password);
            }
        };

        mappings.setReuseItems(true);
        mappingContainer.add(mappings);

        addMappingBtn = new IndicatingAjaxButton("addMappingBtn", new ResourceModel("add")) {

            private static final long serialVersionUID = -4804368561204623354L;

            @Override
            protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
                getMapping().getItems().add(new MappingItemTO());
                target.add(ResourceMappingPanel.this);
            }
        };
        addMappingBtn.setDefaultFormProcessing(false);
        addMappingBtn.setEnabled(this.resourceTO.getConnectorId() != null && this.resourceTO.getConnectorId() > 0);
        mappingContainer.add(addMappingBtn);
    }

    /**
     * Get resource schema names.
     *
     * @param connectorId connector id.
     * @param conf connector configuration properties.
     * @return resource schema names.
     */
    private List<String> getResourceSchemaNames(final Long connectorId, final Set<ConnConfProperty> conf) {
        final List<String> names = new ArrayList<String>();

        try {
            final ConnInstanceTO connInstanceTO = new ConnInstanceTO();
            connInstanceTO.setId(connectorId);
            connInstanceTO.setConfiguration(conf);

            names.addAll(connRestClient.getSchemaNames(connInstanceTO));
        } catch (Exception e) {
            LOG.warn("Error retrieving resource schema names", e);
        }

        return names;
    }

    @Override
    public void onEvent(final IEvent<?> event) {
        if (event.getPayload() instanceof ConnConfModEvent) {
            final AjaxRequestTarget target = ((ConnConfModEvent) event.getPayload()).getTarget();

            final List<ConnConfProperty> conf = ((ConnConfModEvent) event.getPayload()).getConfiguration();

            mappings.removeAll();

            addMappingBtn.setEnabled(resourceTO.getConnectorId() != null && resourceTO.getConnectorId() > 0);

            schemaNames.clear();
            schemaNames.addAll(
                    getResourceSchemaNames(resourceTO.getConnectorId(), new HashSet<ConnConfProperty>(conf)));

            target.add(this);
        }
    }

    /**
     * Set attribute names for a drop down choice list.
     *
     * @param type attribute type.
     * @param toBeUpdated drop down choice to be updated.
     */
    private void setAttrNames(final IntMappingType type, final AjaxDropDownChoicePanel<String> toBeUpdated) {
        toBeUpdated.setRequired(true);
        toBeUpdated.setEnabled(true);

        if (type == null || type.getAttributableType() == null) {
            toBeUpdated.setChoices(Collections.<String>emptyList());
        } else {
            switch (type) {
                // user attribute names
                case UserSchema:
                case RoleSchema:
                case MembershipSchema:
                    toBeUpdated.setChoices(schemaRestClient.getSchemaNames(type.getAttributableType()));
                    break;

                case UserDerivedSchema:
                case RoleDerivedSchema:
                case MembershipDerivedSchema:
                    toBeUpdated.setChoices(schemaRestClient.getDerivedSchemaNames(type.getAttributableType()));
                    break;

                case UserVirtualSchema:
                case RoleVirtualSchema:
                case MembershipVirtualSchema:
                    toBeUpdated.setChoices(schemaRestClient.getVirtualSchemaNames(type.getAttributableType()));
                    break;

                case UserId:
                case Password:
                case Username:
                case RoleId:
                case RoleName:
                default:
                    toBeUpdated.setRequired(false);
                    toBeUpdated.setEnabled(false);
                    toBeUpdated.setChoices(Collections.<String>emptyList());
            }
        }
    }

    /**
     * Enable/Disable accountId checkbox.
     *
     * @param type attribute type.
     * @param accountId accountId checkbox.
     * @param password password checkbox.
     */
    private void setAccountId(final IntMappingType type, final AjaxCheckBoxPanel accountId,
            final AjaxCheckBoxPanel password) {

        if (type != null && type.getAttributableType() != null) {
            switch (type) {
                case UserVirtualSchema:
                case RoleVirtualSchema:
                case MembershipVirtualSchema:
                // Virtual accountId is not permitted
                case Password:
                    // AccountId cannot be derived from password.
                    accountId.setReadOnly(true);
                    accountId.setModelObject(false);
                    break;

                default:
                    if (password.getModelObject()) {
                        accountId.setReadOnly(true);
                        accountId.setModelObject(false);
                    } else {
                        accountId.setReadOnly(false);
                    }
            }
        }
    }

    /**
     * Get all attribute types from a selected attribute type.
     *
     * @param entity entity.
     * @return all attribute types.
     */
    private List<IntMappingType> getAttributeTypes(final AttributableType entity) {
        final List<IntMappingType> res = new ArrayList<IntMappingType>();

        if (entity != null) {
            res.addAll(IntMappingType.getAttributeTypes(AttributableType.valueOf(entity.name())));
        }

        return res;
    }
}
TOP

Related Classes of org.apache.syncope.console.pages.panels.ResourceMappingPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.