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

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

/*
* 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.Collections;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.cxf.jaxrs.ext.search.ConditionType;
import org.apache.cxf.jaxrs.ext.search.SearchBean;
import org.apache.cxf.jaxrs.ext.search.SearchCondition;
import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
import org.apache.syncope.common.search.RoleFiqlSearchConditionBuilder;
import org.apache.syncope.common.search.SearchableFields;
import org.apache.syncope.common.search.SpecialAttr;
import org.apache.syncope.common.search.SyncopeFiqlSearchConditionBuilder;
import org.apache.syncope.common.search.SyncopeProperty;
import org.apache.syncope.common.search.UserFiqlSearchConditionBuilder;
import org.apache.syncope.common.to.ResourceTO;
import org.apache.syncope.common.types.AttributableType;
import org.apache.syncope.common.types.SubjectType;
import org.apache.syncope.console.rest.AuthRestClient;
import org.apache.syncope.console.rest.ResourceRestClient;
import org.apache.syncope.console.rest.SchemaRestClient;
import org.apache.wicket.feedback.FeedbackMessage;
import org.apache.wicket.feedback.IFeedbackMessageFilter;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractSearchPanel extends Panel {

    private static final long serialVersionUID = 5922413053568696414L;

    /**
     * Logger.
     */
    protected static final Logger LOG = LoggerFactory.getLogger(AbstractSearchPanel.class);

    @SpringBean
    protected SchemaRestClient schemaRestClient;

    @SpringBean
    protected ResourceRestClient resourceRestClient;

    @SpringBean
    protected AuthRestClient authRestClient;

    protected IModel<List<String>> dnames;

    protected IModel<List<String>> anames;

    protected IModel<List<String>> resourceNames;

    protected IModel<List<String>> entitlements;

    protected IModel<List<SearchClause.Type>> types;

    protected IModel<List<String>> roleNames;

    protected NotificationPanel searchFeedback;

    protected List<SearchClause> searchClauses;

    protected WebMarkupContainer searchFormContainer;

    protected AttributableType attributableType;

    protected boolean required;

    protected AbstractSearchPanel(final String id, final AttributableType attributableType) {
        this(id, attributableType, null, true);
    }

    protected AbstractSearchPanel(final String id, final AttributableType attributableType,
            final String fiql, final boolean required) {

        super(id);
        populate();

        this.attributableType = attributableType;
        this.required = required;

        setOutputMarkupId(true);

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

        searchFeedback = new NotificationPanel("searchFeedback", "notificationpanel_top_right",
                new IFeedbackMessageFilter() {

                    private static final long serialVersionUID = 6895024863321391672L;

                    @Override
                    public boolean accept(final FeedbackMessage message) {
                        boolean result;

                        // messages reported on the session have a null reporter
                        if (message.getReporter() == null) {
                            result = false;
                        } else {
                            // only accept messages coming from the children of the search form container
                            result = searchFormContainer.contains(message.getReporter(), true);
                        }

                        return result;
                    }
                });
        searchFeedback.setOutputMarkupId(true);
        add(searchFeedback);

        this.searchClauses = new ArrayList<SearchClause>();
        this.searchClauses.add(new SearchClause());
        if (StringUtils.isNotBlank(fiql)) {
            try {
                FiqlParser<SearchBean> fiqlParser = new FiqlParser<SearchBean>(
                        SearchBean.class, SyncopeFiqlSearchConditionBuilder.CONTEXTUAL_PROPERTIES);
                List<SearchClause> parsed = getSearchClauses(fiqlParser.parse(fiql));

                this.searchClauses.clear();
                this.searchClauses.addAll(parsed);
            } catch (Exception e) {
                LOG.error("Unparseable FIQL expression '{}'", fiql, e);
            }
        }

        searchFormContainer.add(new SearchView("searchView", searchClauses, searchFormContainer, required,
                types, anames, dnames, roleNames, resourceNames, entitlements));
        add(searchFormContainer);
    }

    protected void populate() {
        dnames = new LoadableDetachableModel<List<String>>() {

            private static final long serialVersionUID = 5275935387613157437L;

            @Override
            protected List<String> load() {
                return SearchableFields.get(attributableType == AttributableType.USER
                        ? SubjectType.USER : SubjectType.ROLE);
            }
        };

        anames = new LoadableDetachableModel<List<String>>() {

            private static final long serialVersionUID = 5275935387613157437L;

            @Override
            protected List<String> load() {
                return schemaRestClient.getSchemaNames(attributableType);
            }
        };

        resourceNames = new LoadableDetachableModel<List<String>>() {

            private static final long serialVersionUID = 5275935387613157437L;

            @Override
            protected List<String> load() {
                List<ResourceTO> resourceTOs = resourceRestClient.getAll();

                List<String> result = new ArrayList<String>(resourceTOs.size());

                for (ResourceTO resource : resourceTOs) {
                    result.add(resource.getName());
                }

                return result;
            }
        };

        entitlements = new LoadableDetachableModel<List<String>>() {

            private static final long serialVersionUID = 5275935387613157437L;

            @Override
            protected List<String> load() {
                List<String> result = authRestClient.getOwnedEntitlements();
                Collections.sort(result);
                return result;
            }
        };
    }

    public NotificationPanel getSearchFeedback() {
        return searchFeedback;
    }

    private SearchClause getPrimitiveSearchClause(final SearchCondition<SearchBean> sc) {
        SearchClause searchClause = new SearchClause();

        String property = sc.getCondition().getKeySet().iterator().next();
        searchClause.setProperty(property);
        String value = sc.getCondition().get(property);
        searchClause.setValue(value);

        if (SpecialAttr.ROLES.toString().equals(property)) {
            searchClause.setType(SearchClause.Type.MEMBERSHIP);
            for (String label : roleNames.getObject()) {
                if (value.equals(label.substring(0, label.indexOf(' ')))) {
                    searchClause.setProperty(label);
                }
            }
        } else if (SpecialAttr.RESOURCES.toString().equals(property)) {
            searchClause.setType(SearchClause.Type.RESOURCE);
        } else if (SpecialAttr.ENTITLEMENTS.toString().equals(property)) {
            searchClause.setType(SearchClause.Type.ENTITLEMENT);
        } else {
            searchClause.setType(SearchClause.Type.ATTRIBUTE);
        }

        switch (sc.getConditionType()) {
            case EQUALS:
                searchClause.setComparator(SpecialAttr.NULL.toString().equals(value)
                        ? SearchClause.Comparator.IS_NULL : SearchClause.Comparator.EQUALS);
                break;

            case NOT_EQUALS:
                searchClause.setComparator(SpecialAttr.NULL.toString().equals(value)
                        ? SearchClause.Comparator.IS_NOT_NULL : SearchClause.Comparator.NOT_EQUALS);
                break;

            case GREATER_OR_EQUALS:
                searchClause.setComparator(SearchClause.Comparator.GREATER_OR_EQUALS);
                break;

            case GREATER_THAN:
                searchClause.setComparator(SearchClause.Comparator.GREATER_THAN);
                break;

            case LESS_OR_EQUALS:
                searchClause.setComparator(SearchClause.Comparator.LESS_OR_EQUALS);
                break;

            case LESS_THAN:
                searchClause.setComparator(SearchClause.Comparator.LESS_THAN);
                break;

            default:
                break;
        }

        return searchClause;
    }

    private List<SearchClause> getCompoundSearchClause(final SearchCondition<SearchBean> sc) {
        List<SearchClause> clauses = new ArrayList<SearchClause>();

        for (SearchCondition<SearchBean> searchCondition : sc.getSearchConditions()) {
            if (searchCondition.getStatement() == null) {
                clauses.addAll(getCompoundSearchClause(searchCondition));
            } else {
                SearchClause clause = getPrimitiveSearchClause(searchCondition);
                if (sc.getConditionType() == ConditionType.AND) {
                    clause.setOperator(SearchClause.Operator.AND);
                }
                if (sc.getConditionType() == ConditionType.OR) {
                    clause.setOperator(SearchClause.Operator.OR);
                }
                clauses.add(clause);
            }
        }

        return clauses;
    }

    private List<SearchClause> getSearchClauses(final SearchCondition<SearchBean> sc) {
        List<SearchClause> clauses = new ArrayList<SearchClause>();

        if (sc.getStatement() == null) {
            clauses.addAll(getCompoundSearchClause(sc));
        } else {
            clauses.add(getPrimitiveSearchClause(sc));
        }

        return clauses;
    }

    protected abstract SyncopeFiqlSearchConditionBuilder getSearchConditionBuilder();

    public String buildFIQL() {
        LOG.debug("Generating FIQL from List<SearchClause>: {}", searchClauses);

        if (searchClauses.isEmpty() || searchClauses.get(0).getType() == null) {
            return StringUtils.EMPTY;
        }

        SyncopeFiqlSearchConditionBuilder builder = getSearchConditionBuilder();

        CompleteCondition prevCondition;
        CompleteCondition condition = null;
        for (int i = 0; i < searchClauses.size(); i++) {
            prevCondition = condition;

            switch (searchClauses.get(i).getType()) {
                case ENTITLEMENT:
                    condition = searchClauses.get(i).getComparator() == SearchClause.Comparator.EQUALS
                            ? ((RoleFiqlSearchConditionBuilder) builder).
                            hasEntitlements(searchClauses.get(i).getProperty())
                            : ((RoleFiqlSearchConditionBuilder) builder).
                            hasNotEntitlements(searchClauses.get(i).getProperty());
                    break;

                case MEMBERSHIP:
                    Long roleId = NumberUtils.toLong(searchClauses.get(i).getProperty().split(" ")[0]);
                    condition = searchClauses.get(i).getComparator() == SearchClause.Comparator.EQUALS
                            ? ((UserFiqlSearchConditionBuilder) builder).hasRoles(roleId)
                            : ((UserFiqlSearchConditionBuilder) builder).hasNotRoles(roleId);
                    break;

                case RESOURCE:
                    condition = searchClauses.get(i).getComparator() == SearchClause.Comparator.EQUALS
                            ? builder.hasResources(searchClauses.get(i).getProperty())
                            : builder.hasNotResources(searchClauses.get(i).getProperty());
                    break;

                case ATTRIBUTE:
                    SyncopeProperty property = builder.is(searchClauses.get(i).getProperty());
                    switch (searchClauses.get(i).getComparator()) {
                        case IS_NULL:
                            condition = builder.isNull(searchClauses.get(i).getProperty());
                            break;

                        case IS_NOT_NULL:
                            condition = builder.isNotNull(searchClauses.get(i).getProperty());
                            break;

                        case LESS_THAN:
                            condition = StringUtils.isNumeric(searchClauses.get(i).getProperty())
                                    ? property.lessThan(NumberUtils.toDouble(searchClauses.get(i).getValue()))
                                    : property.lexicalBefore(searchClauses.get(i).getValue());
                            break;

                        case LESS_OR_EQUALS:
                            condition = StringUtils.isNumeric(searchClauses.get(i).getProperty())
                                    ? property.lessOrEqualTo(NumberUtils.toDouble(searchClauses.get(i).getValue()))
                                    : property.lexicalNotAfter(searchClauses.get(i).getValue());
                            break;

                        case GREATER_THAN:
                            condition = StringUtils.isNumeric(searchClauses.get(i).getProperty())
                                    ? property.greaterThan(NumberUtils.toDouble(searchClauses.get(i).getValue()))
                                    : property.lexicalAfter(searchClauses.get(i).getValue());
                            break;

                        case GREATER_OR_EQUALS:
                            condition = StringUtils.isNumeric(searchClauses.get(i).getProperty())
                                    ? property.greaterOrEqualTo(NumberUtils.toDouble(searchClauses.get(i).getValue()))
                                    : property.lexicalNotBefore(searchClauses.get(i).getValue());
                            break;

                        case NOT_EQUALS:
                            condition = property.notEqualTo(searchClauses.get(i).getValue());
                            break;

                        case EQUALS:
                        default:
                            condition = property.equalTo(searchClauses.get(i).getValue());
                            break;
                    }
                default:
                    break;
            }

            if (i > 0) {
                if (searchClauses.get(i).getOperator() == SearchClause.Operator.AND) {
                    condition = builder.and(prevCondition, condition);
                }
                if (searchClauses.get(i).getOperator() == SearchClause.Operator.OR) {
                    condition = builder.or(prevCondition, condition);
                }
            }
        }

        String fiql = condition == null ? StringUtils.EMPTY : condition.query();
        LOG.debug("Generated FIQL: {}", fiql);
        return fiql;
    }
}
TOP

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

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.