001// Generated by delombok at Mon Oct 12 22:51:05 BST 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.interactions.managed.ManagedAction;
034import org.apache.isis.core.metamodel.interactions.managed.ManagedCollection;
035import org.apache.isis.core.metamodel.interactions.managed.ManagedProperty;
036import org.apache.isis.core.metamodel.spec.ManagedObject;
037import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
038import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
039import org.apache.isis.viewer.restfulobjects.rendering.service.conneg.ContentNegotiationService;
040import org.apache.isis.viewer.restfulobjects.rendering.service.conneg.ContentNegotiationServiceForRestfulObjectsV1_0;
041
042@Service
043@Named("isisRoRendering.RepresentationServiceContentNegotiator")
044@Order(OrderPrecedence.EARLY)
045@Primary
046@Qualifier("ContentNegotiator")
047public class RepresentationServiceContentNegotiator implements RepresentationService {
048    @Inject
049    private List<ContentNegotiationService> contentNegotiationServices;
050
051    @Override
052    public Response objectRepresentation(final IResourceContext renderContext, final ManagedObject objectAdapter) {
053        final ResponseBuilder responseBuilder = buildResponse(connegService -> connegService.buildResponse(renderContext, objectAdapter));
054        assertContentNegotiationServiceHandled(responseBuilder);
055        return buildResponse(responseBuilder);
056    }
057
058    @Override
059    public Response propertyDetails(final IResourceContext renderContext, final ManagedProperty objectAndProperty) {
060        final ResponseBuilder responseBuilder = buildResponse(connegService -> connegService.buildResponse(renderContext, objectAndProperty));
061        assertContentNegotiationServiceHandled(responseBuilder);
062        return buildResponse(responseBuilder);
063    }
064
065    @Override
066    public Response collectionDetails(final IResourceContext renderContext, final ManagedCollection objectAndCollection) {
067        final ResponseBuilder responseBuilder = buildResponse(connegService -> connegService.buildResponse(renderContext, objectAndCollection));
068        assertContentNegotiationServiceHandled(responseBuilder);
069        return buildResponse(responseBuilder);
070    }
071
072    @Override
073    public Response actionPrompt(final IResourceContext renderContext, final ManagedAction objectAndAction) {
074        final ResponseBuilder responseBuilder = buildResponse(connegService -> connegService.buildResponse(renderContext, objectAndAction));
075        assertContentNegotiationServiceHandled(responseBuilder);
076        return buildResponse(responseBuilder);
077    }
078
079    @Override
080    public Response actionResult(final IResourceContext renderContext, final ObjectAndActionInvocation objectAndActionInvocation) {
081        final ResponseBuilder responseBuilder = buildResponse(connegService -> connegService.buildResponse(renderContext, objectAndActionInvocation));
082        assertContentNegotiationServiceHandled(responseBuilder);
083        return buildResponse(responseBuilder);
084    }
085
086    void assertContentNegotiationServiceHandled(final ResponseBuilder responseBuilder) {
087        if (responseBuilder == null) {
088            throw new IllegalStateException("Could not locate " + ContentNegotiationService.class.getSimpleName() + " to handle request");
089        }
090    }
091
092    /**
093     * Iterates over all {@link #contentNegotiationServices injected} {@link ContentNegotiationService}s to find one
094
095     * that returns a {@link ResponseBuilder} using the provided function.
096
097     *
098
099     * <p>
100
101     *     There will always be at least one such service, namely the
102
103     *     {@link ContentNegotiationServiceForRestfulObjectsV1_0}.
104
105     * </p>
106
107     *
108
109     * @param connegServiceBuildResponse - the function to ask of the {@link ContentNegotiationService}.
110     */
111    ResponseBuilder buildResponse(Function<ContentNegotiationService, ResponseBuilder> connegServiceBuildResponse) {
112        for (final org.apache.isis.viewer.restfulobjects.rendering.service.conneg.ContentNegotiationService contentNegotiationService : contentNegotiationServices) {
113            final javax.ws.rs.core.Response.ResponseBuilder responseBuilder = connegServiceBuildResponse.apply(contentNegotiationService);
114            if (responseBuilder != null) {
115                return responseBuilder;
116            }
117        }
118        return null;
119    }
120
121    /**
122     * Override to allow further customization.
123     */
124    protected Response buildResponse(final ResponseBuilder responseBuilder) {
125        return responseBuilder.build();
126    }
127}