001// Generated by delombok at Thu Mar 19 15:24:58 GMT 2020
002/*
003 *  Licensed to the Apache Software Foundation (ASF) under one
004 *  or more contributor license agreements.  See the NOTICE file
005 *  distributed with this work for additional information
006 *  regarding copyright ownership.  The ASF licenses this file
007 *  to you under the Apache License, Version 2.0 (the
008 *  "License"); you may not use this file except in compliance
009 *  with the License.  You may obtain a copy of the License at
010 *
011 *        http://www.apache.org/licenses/LICENSE-2.0
012 *
013 *  Unless required by applicable law or agreed to in writing,
014 *  software distributed under the License is distributed on an
015 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 *  KIND, either express or implied.  See the License for the
017 *  specific language governing permissions and limitations
018 *  under the License.
019 */
020package org.apache.isis.viewer.restfulobjects.rendering.service;
021
022import java.util.List;
023import java.util.function.Function;
024import javax.inject.Inject;
025import javax.inject.Named;
026import javax.ws.rs.core.Response;
027import javax.ws.rs.core.Response.ResponseBuilder;
028import org.springframework.beans.factory.annotation.Qualifier;
029import org.springframework.context.annotation.Primary;
030import org.springframework.core.annotation.Order;
031import org.springframework.stereotype.Service;
032import org.apache.isis.applib.annotation.OrderPrecedence;
033import org.apache.isis.core.metamodel.spec.ManagedObject;
034import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
035import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ActionResultReprRenderer.SelfLink;
036import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.MemberReprMode;
037import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndAction;
038import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
039import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndCollection;
040import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndProperty;
041import org.apache.isis.viewer.restfulobjects.rendering.service.conneg.ContentNegotiationService;
042import org.apache.isis.viewer.restfulobjects.rendering.service.conneg.ContentNegotiationServiceForRestfulObjectsV1_0;
043
044@Service
045@Named("isisRoRendering.RepresentationServiceContentNegotiator")
046@Order(OrderPrecedence.EARLY)
047@Primary
048@Qualifier("ContentNegotiator")
049public class RepresentationServiceContentNegotiator implements RepresentationService {
050    @Inject
051    private List<ContentNegotiationService> contentNegotiationServices;
052
053    @Override
054    public Response objectRepresentation(final IResourceContext renderContext, final ManagedObject objectAdapter) {
055        final ResponseBuilder responseBuilder = buildResponse(connegService -> connegService.buildResponse(renderContext, objectAdapter));
056        assertContentNegotiationServiceHandled(responseBuilder);
057        return buildResponse(responseBuilder);
058    }
059
060    @Override
061    public Response propertyDetails(final IResourceContext renderContext, final ObjectAndProperty objectAndProperty, final MemberReprMode memberReprMode) {
062        final ResponseBuilder responseBuilder = buildResponse(connegService -> connegService.buildResponse(renderContext, objectAndProperty));
063        assertContentNegotiationServiceHandled(responseBuilder);
064        return buildResponse(responseBuilder);
065    }
066
067    @Override
068    public Response collectionDetails(final IResourceContext renderContext, final ObjectAndCollection objectAndCollection, final MemberReprMode memberReprMode) {
069        final ResponseBuilder responseBuilder = buildResponse(connegService -> connegService.buildResponse(renderContext, objectAndCollection));
070        assertContentNegotiationServiceHandled(responseBuilder);
071        return buildResponse(responseBuilder);
072    }
073
074    @Override
075    public Response actionPrompt(final IResourceContext renderContext, final ObjectAndAction objectAndAction) {
076        final ResponseBuilder responseBuilder = buildResponse(connegService -> connegService.buildResponse(renderContext, objectAndAction));
077        assertContentNegotiationServiceHandled(responseBuilder);
078        return buildResponse(responseBuilder);
079    }
080
081    @Override
082    public Response actionResult(final IResourceContext renderContext, final ObjectAndActionInvocation objectAndActionInvocation, final SelfLink selfLink) {
083        final ResponseBuilder responseBuilder = buildResponse(connegService -> connegService.buildResponse(renderContext, objectAndActionInvocation));
084        assertContentNegotiationServiceHandled(responseBuilder);
085        return buildResponse(responseBuilder);
086    }
087
088    void assertContentNegotiationServiceHandled(final ResponseBuilder responseBuilder) {
089        if (responseBuilder == null) {
090            throw new IllegalStateException("Could not locate " + ContentNegotiationService.class.getSimpleName() + " to handle request");
091        }
092    }
093
094    /**
095     * Iterates over all {@link #contentNegotiationServices injected} {@link ContentNegotiationService}s to find one
096
097     * that returns a {@link ResponseBuilder} using the provided function.
098
099     *
100
101     * <p>
102
103     *     There will always be at least one such service, namely the
104
105     *     {@link ContentNegotiationServiceForRestfulObjectsV1_0}.
106
107     * </p>
108
109     *
110
111     * @param connegServiceBuildResponse - the function to ask of the {@link ContentNegotiationService}.
112     */
113    ResponseBuilder buildResponse(Function<ContentNegotiationService, ResponseBuilder> connegServiceBuildResponse) {
114        for (final org.apache.isis.viewer.restfulobjects.rendering.service.conneg.ContentNegotiationService contentNegotiationService : contentNegotiationServices) {
115            final javax.ws.rs.core.Response.ResponseBuilder responseBuilder = connegServiceBuildResponse.apply(contentNegotiationService);
116            if (responseBuilder != null) {
117                return responseBuilder;
118            }
119        }
120        return null;
121    }
122
123    /**
124     * Override to allow further customization.
125     */
126    protected Response buildResponse(final ResponseBuilder responseBuilder) {
127        return responseBuilder.build();
128    }
129}