Package org.apache.syncope.core.services

Source Code of org.apache.syncope.core.services.AbstractServiceImpl

/*
* 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.core.services;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.ext.search.SearchBean;
import org.apache.cxf.jaxrs.ext.search.SearchCondition;
import org.apache.cxf.jaxrs.ext.search.SearchContext;
import org.apache.syncope.common.AbstractBaseBean;
import org.apache.syncope.common.SyncopeClientException;
import org.apache.syncope.common.services.JAXRSService;
import org.apache.syncope.common.reqres.PagedResult;
import org.apache.syncope.common.types.ClientExceptionType;
import org.apache.syncope.common.types.Preference;
import org.apache.syncope.common.types.RESTHeaders;
import org.apache.syncope.core.persistence.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.dao.search.SearchCond;
import org.apache.syncope.core.rest.data.SearchCondVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

abstract class AbstractServiceImpl implements JAXRSService {

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

    protected static final String OPTIONS_ALLOW = "GET,POST,OPTIONS,HEAD";

    @Context
    protected UriInfo uriInfo;

    @Context
    protected MessageContext messageContext;

    @Context
    protected SearchContext searchContext;

    /**
     * Reads <tt>Prefer</tt> header from request and parses into a <tt>Preference</tt> instance.
     *
     * @return a <tt>Preference</tt> instance matching the passed <tt>Prefer</tt> header,
     * or <tt>Preference.NONE</tt> if missing.
     */
    protected Preference getPreference() {
        return Preference.fromString(messageContext.getHttpHeaders().getHeaderString(RESTHeaders.PREFER));
    }

    /**
     * Builds response to successful <tt>create</tt> request, taking into account any <tt>Prefer</tt> header.
     *
     * @param id identifier of the created entity
     * @param entity the entity just created
     * @return response to successful <tt>create</tt> request
     */
    protected Response createResponse(final Object id, final Object entity) {
        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(id)).build();

        Response.ResponseBuilder builder = Response.
                created(location).
                header(RESTHeaders.RESOURCE_ID, id);

        switch (getPreference()) {
            case RETURN_NO_CONTENT:
                break;

            case RETURN_CONTENT:
            case NONE:
            default:
                builder = builder.entity(entity);
                break;

        }
        if (getPreference() == Preference.RETURN_CONTENT || getPreference() == Preference.RETURN_NO_CONTENT) {
            builder = builder.header(RESTHeaders.PREFERENCE_APPLIED, getPreference().toString());
        }

        return builder.build();
    }

    /**
     * Builds response to successful modification request, taking into account any <tt>Prefer</tt> header.
     *
     * @param entity the entity just modified
     * @return response to successful modification request
     */
    protected Response modificationResponse(final Object entity) {
        Response.ResponseBuilder builder;
        switch (getPreference()) {
            case RETURN_NO_CONTENT:
                builder = Response.noContent();
                break;

            case RETURN_CONTENT:
            case NONE:
            default:
                builder = Response.ok(entity);
                break;
        }
        if (getPreference() == Preference.RETURN_CONTENT || getPreference() == Preference.RETURN_NO_CONTENT) {
            builder = builder.header(RESTHeaders.PREFERENCE_APPLIED, getPreference().toString());
        }

        return builder.build();
    }

    protected void checkETag(final String etag) {
        Response.ResponseBuilder builder = messageContext.getRequest().evaluatePreconditions(new EntityTag(etag));
        if (builder != null) {
            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.ConcurrentModification);
            sce.getElements().add("Mismatching ETag value");
            throw sce;
        }
    }

    protected SearchCond getSearchCond(final String fiql) {
        try {
            SearchCondVisitor visitor = new SearchCondVisitor();
            SearchCondition<SearchBean> sc = searchContext.getCondition(fiql, SearchBean.class);
            sc.accept(visitor);

            return visitor.getQuery();
        } catch (Exception e) {
            LOG.error("Invalid FIQL expression: {}", fiql, e);

            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
            sce.getElements().add(fiql);
            throw sce;
        }
    }

    protected List<OrderByClause> getOrderByClauses(final String orderBy) {
        if (StringUtils.isBlank(orderBy)) {
            return Collections.<OrderByClause>emptyList();
        }

        List<OrderByClause> result = new ArrayList<OrderByClause>();

        for (String clause : orderBy.split(",")) {
            String[] elems = clause.split(" ");

            if (elems.length > 0 && StringUtils.isNotBlank(elems[0])) {
                OrderByClause obc = new OrderByClause();
                obc.setField(elems[0].trim());
                if (elems.length > 1 && StringUtils.isNotBlank(elems[1])) {
                    obc.setDirection(elems[1].trim().equalsIgnoreCase(OrderByClause.Direction.ASC.name())
                            ? OrderByClause.Direction.ASC : OrderByClause.Direction.DESC);
                }
                result.add(obc);
            }
        }

        return result;
    }

    /**
     * Builds a paged result out of a list of items and additional information.
     *
     * @param <T> result type
     * @param list bare list of items to be returned
     * @param page current page
     * @param size requested size
     * @param totalCount total result size (not considering pagination)
     * @return paged result
     */
    protected <T extends AbstractBaseBean> PagedResult<T> buildPagedResult(
            final List<T> list, final int page, final int size, final int totalCount) {

        PagedResult<T> result = new PagedResult<T>();
        result.getResult().addAll(list);

        result.setPage(page);
        result.setSize(result.getResult().size());
        result.setTotalCount(totalCount);

        UriBuilder builder = uriInfo.getAbsolutePathBuilder();
        MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
        for (Map.Entry<String, List<String>> queryParam : queryParams.entrySet()) {
            builder = builder.queryParam(queryParam.getKey(), queryParam.getValue().toArray());
        }

        if (result.getPage() > 1) {
            result.setPrev(builder.
                    replaceQueryParam(PARAM_PAGE, result.getPage() - 1).
                    replaceQueryParam(PARAM_SIZE, size).
                    build());
        }
        if ((result.getPage() - 1) * size + result.getSize() < totalCount) {
            result.setNext(builder.
                    replaceQueryParam(PARAM_PAGE, result.getPage() + 1).
                    replaceQueryParam(PARAM_SIZE, size).
                    build());
        }

        return result;
    }

}
TOP

Related Classes of org.apache.syncope.core.services.AbstractServiceImpl

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.