Package org.apache.isis.viewer.json.viewer.resources.domaintypes

Source Code of org.apache.isis.viewer.json.viewer.resources.domaintypes.DomainTypeResourceServerside

/*
*  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.isis.viewer.json.viewer.resources.domaintypes;

import java.util.Collection;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.google.common.base.Strings;

import org.jboss.resteasy.annotations.ClientResponseType;

import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
import org.apache.isis.viewer.json.applib.JsonRepresentation;
import org.apache.isis.viewer.json.applib.RepresentationType;
import org.apache.isis.viewer.json.applib.RestfulMediaType;
import org.apache.isis.viewer.json.applib.RestfulResponse.HttpStatusCode;
import org.apache.isis.viewer.json.applib.domaintypes.DomainTypeResource;
import org.apache.isis.viewer.json.applib.links.Rel;
import org.apache.isis.viewer.json.viewer.JsonApplicationException;
import org.apache.isis.viewer.json.viewer.representations.LinkBuilder;
import org.apache.isis.viewer.json.viewer.representations.RendererFactory;
import org.apache.isis.viewer.json.viewer.resources.ResourceAbstract;
import org.apache.isis.viewer.json.viewer.resources.domainobjects.DomainObjectReprRenderer;
import org.apache.isis.viewer.json.viewer.resources.domainobjects.DomainResourceHelper;
import org.apache.isis.viewer.json.viewer.util.UrlParserUtils;

/**
* Implementation note: it seems to be necessary to annotate the implementation
* with {@link Path} rather than the interface (at least under RestEasy 1.0.2
* and 1.1-RC2).
*/
@Path("/domainTypes")
public class DomainTypeResourceServerside extends ResourceAbstract implements DomainTypeResource {

    @Override
    @GET
    @Path("/")
    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_TYPE_LIST })
    public Response domainTypes() {
        final RepresentationType representationType = RepresentationType.TYPE_LIST;
        init(representationType);

        final Collection<ObjectSpecification> allSpecifications = getSpecificationLoader().allSpecifications();

        final RendererFactory rendererFactory = rendererFactoryRegistry.find(representationType);

        final TypeListReprRenderer renderer = (TypeListReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
        renderer.with(allSpecifications).includesSelf();

        return responseOfOk(renderer, Caching.ONE_DAY).build();
    }

    @Override
    @GET
    @Path("/{domainType}")
    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_DOMAIN_TYPE })
    public Response domainType(@PathParam("domainType") final String domainType) {

        final RepresentationType representationType = RepresentationType.DOMAIN_TYPE;
        init(representationType);

        final ObjectSpecification objectSpec = getSpecificationLoader().loadSpecification(domainType);

        final RendererFactory rendererFactory = rendererFactoryRegistry.find(representationType);

        final DomainTypeReprRenderer renderer = (DomainTypeReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
        renderer.with(objectSpec).includesSelf();

        return responseOfOk(renderer, Caching.ONE_DAY).build();
    }

    @Override
    @GET
    @Path("/{domainType}/properties/{propertyId}")
    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_PROPERTY_DESCRIPTION })
    public Response typeProperty(@PathParam("domainType") final String domainType, @PathParam("propertyId") final String propertyId) {
        final RepresentationType representationType = RepresentationType.PROPERTY_DESCRIPTION;
        init(representationType);

        final ObjectSpecification parentSpec = getSpecificationLoader().loadSpecification(domainType);
        if (parentSpec == null) {
            throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
        }

        final ObjectMember objectMember = parentSpec.getAssociation(propertyId);
        if (objectMember == null || objectMember.isOneToManyAssociation()) {
            throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
        }
        final OneToOneAssociation property = (OneToOneAssociation) objectMember;

        final RendererFactory rendererFactory = rendererFactoryRegistry.find(representationType);

        final PropertyDescriptionReprRenderer renderer = (PropertyDescriptionReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
        renderer.with(new ParentSpecAndProperty(parentSpec, property)).includesSelf();

        return responseOfOk(renderer, Caching.ONE_DAY).build();
    }

    @Override
    @GET
    @Path("/{domainType}/collections/{collectionId}")
    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_COLLECTION_DESCRIPTION })
    public Response typeCollection(@PathParam("domainType") final String domainType, @PathParam("collectionId") final String collectionId) {
        final RepresentationType representationType = RepresentationType.COLLECTION_DESCRIPTION;
        init(representationType);

        final ObjectSpecification parentSpec = getSpecificationLoader().loadSpecification(domainType);
        if (parentSpec == null) {
            throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
        }

        final ObjectMember objectMember = parentSpec.getAssociation(collectionId);
        if (objectMember == null || objectMember.isOneToOneAssociation()) {
            throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
        }
        final OneToManyAssociation collection = (OneToManyAssociation) objectMember;

        final RendererFactory rendererFactory = rendererFactoryRegistry.find(representationType);

        final CollectionDescriptionReprRenderer renderer = (CollectionDescriptionReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
        renderer.with(new ParentSpecAndCollection(parentSpec, collection)).includesSelf();

        return responseOfOk(renderer, Caching.ONE_DAY).build();
    }

    @Override
    @GET
    @Path("/{domainType}/actions/{actionId}")
    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_DESCRIPTION })
    public Response typeAction(@PathParam("domainType") final String domainType, @PathParam("actionId") final String actionId) {
        final RepresentationType representationType = RepresentationType.ACTION_DESCRIPTION;
        init(representationType);

        final ObjectSpecification parentSpec = getSpecificationLoader().loadSpecification(domainType);
        if (parentSpec == null) {
            throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
        }

        final ObjectMember objectMember = parentSpec.getObjectAction(actionId);
        if (objectMember == null) {
            throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
        }
        final ObjectAction action = (ObjectAction) objectMember;

        final RendererFactory rendererFactory = rendererFactoryRegistry.find(representationType);

        final ActionDescriptionReprRenderer renderer = (ActionDescriptionReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
        renderer.with(new ParentSpecAndAction(parentSpec, action)).includesSelf();

        return responseOfOk(renderer, Caching.ONE_DAY).build();
    }

    @Override
    @GET
    @Path("/{domainType}/actions/{actionId}/params/{paramName}")
    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_PARAMETER_DESCRIPTION })
    public Response typeActionParam(@PathParam("domainType") final String domainType, @PathParam("actionId") final String actionId, @PathParam("paramName") final String paramName) {
        final RepresentationType representationType = RepresentationType.ACTION_PARAMETER_DESCRIPTION;
        init(representationType);

        final ObjectSpecification parentSpec = getSpecificationLoader().loadSpecification(domainType);
        if (parentSpec == null) {
            throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
        }

        final ObjectMember objectMember = parentSpec.getObjectAction(actionId);
        if (objectMember == null) {
            throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
        }
        final ObjectAction parentAction = (ObjectAction) objectMember;

        final ObjectActionParameter actionParam = parentAction.getParameterByName(paramName);

        final RendererFactory rendererFactory = rendererFactoryRegistry.find(representationType);

        final ActionParameterDescriptionReprRenderer renderer = (ActionParameterDescriptionReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
        renderer.with(new ParentSpecAndActionParam(parentSpec, actionParam)).includesSelf();

        return responseOfOk(renderer, Caching.ONE_DAY).build();
    }

    // //////////////////////////////////////////////////////////
    // domain type actions
    // //////////////////////////////////////////////////////////

    @Override
    @GET
    @Path("/{domainType}/typeactions/isSubtypeOf/invoke")
    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
    public Response domainTypeIsSubtypeOf(@PathParam("domainType") final String domainType, @QueryParam("supertype") final String superTypeStr, // simple
                                                                                                                                                // style
            @QueryParam("args") final String args // formal style
    ) {

        final RepresentationType representationType = RepresentationType.TYPE_ACTION_RESULT;
        init();

        final String supertype = domainTypeFor(superTypeStr, args, "supertype");

        final ObjectSpecification domainTypeSpec = getSpecificationLoader().loadSpecification(domainType);
        final ObjectSpecification supertypeSpec = getSpecificationLoader().loadSpecification(supertype);

        final RendererFactory rendererFactory = rendererFactoryRegistry.find(representationType);
        final TypeActionResultReprRenderer renderer = (TypeActionResultReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());

        final String url = "domainTypes/" + domainTypeSpec.getFullIdentifier() + "/typeactions/isSubtypeOf/invoke";
        final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.SELF, RepresentationType.TYPE_ACTION_RESULT, url);
        final JsonRepresentation arguments = DomainTypeReprRenderer.argumentsTo(getResourceContext(), "supertype", supertypeSpec);
        final JsonRepresentation selfLink = linkBuilder.withArguments(arguments).build();

        final boolean value = domainTypeSpec.isOfType(supertypeSpec);
        renderer.with(domainTypeSpec).withSelf(selfLink).withValue(value);

        return responseOfOk(renderer, Caching.ONE_DAY).build();
    }

    @Override
    @GET
    @Path("/{domainType}/typeactions/isSupertypeOf/invoke")
    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
    public Response domainTypeIsSupertypeOf(@PathParam("domainType") final String domainType, @QueryParam("subtype") final String subTypeStr, // simple
                                                                                                                                              // style
            @QueryParam("args") final String args // formal style
    ) {

        final RepresentationType representationType = RepresentationType.TYPE_ACTION_RESULT;
        init();

        final String subtype = domainTypeFor(subTypeStr, args, "subtype");

        final ObjectSpecification domainTypeSpec = getSpecificationLoader().loadSpecification(domainType);
        final ObjectSpecification subtypeSpec = getSpecificationLoader().loadSpecification(subtype);

        final RendererFactory rendererFactory = rendererFactoryRegistry.find(representationType);
        final TypeActionResultReprRenderer renderer = (TypeActionResultReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());

        final String url = "domainTypes/" + domainTypeSpec.getFullIdentifier() + "/typeactions/isSupertypeOf/invoke";
        final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.SELF, RepresentationType.TYPE_ACTION_RESULT, url);
        final JsonRepresentation arguments = DomainTypeReprRenderer.argumentsTo(getResourceContext(), "subtype", subtypeSpec);
        final JsonRepresentation selfLink = linkBuilder.withArguments(arguments).build();

        final boolean value = subtypeSpec.isOfType(domainTypeSpec);
        renderer.with(domainTypeSpec).withSelf(selfLink).withValue(value);

        return responseOfOk(renderer, Caching.ONE_DAY).build();
    }

    @Override
    @GET
    @Path("/{domainType}/typeactions/newTransientInstance/invoke")
    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
    @ClientResponseType(entityType = String.class)
    public Response newTransientInstance(@PathParam("domainType") final String domainTypeStr, @QueryParam("args") final String args) {

        final RepresentationType representationType = RepresentationType.TYPE_ACTION_RESULT;
        init(representationType);

        final String domainType = domainTypeFor(domainTypeStr, args, "domainType");

        final ObjectSpecification domainTypeSpec = getSpecificationLoader().loadSpecification(domainType);

        final RendererFactory rendererFactory = rendererFactoryRegistry.find(representationType);
        final TypeActionResultReprRenderer renderer = (TypeActionResultReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());

        final String url = "domainTypes/" + domainTypeSpec.getFullIdentifier() + "/typeactions/newTransientInstance/invoke";
        final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.SELF, RepresentationType.TYPE_ACTION_RESULT, url);
        final JsonRepresentation selfLink = linkBuilder.build();

        final RendererFactory domainObjectRendererFactory = rendererFactoryRegistry.find(RepresentationType.DOMAIN_OBJECT);
        final DomainObjectReprRenderer domainObjectRenderer = (DomainObjectReprRenderer) domainObjectRendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
        final ObjectAdapter transientInstance = getResourceContext().getPersistenceSession().createInstance(domainTypeSpec);
        domainObjectRenderer.with(transientInstance).includesSelf();

        renderer.with(domainTypeSpec).withSelf(selfLink).withValue(domainObjectRenderer.render());

        return responseOfOk(renderer, Caching.ONE_DAY).build();
    }

    private static String domainTypeFor(final String domainTypeStr, final String argumentsQueryString, final String argsParamName) {
        // simple style; simple return
        if (!Strings.isNullOrEmpty(domainTypeStr)) {
            return domainTypeStr;
        }

        // formal style; must parse from args that has a link with an href to
        // the domain type
        final String href = linkFromFormalArgs(argumentsQueryString, argsParamName);
        return UrlParserUtils.domainTypeFrom(href);
    }

    private static String linkFromFormalArgs(final String argumentsQueryString, final String paramName) {
        final JsonRepresentation arguments = DomainResourceHelper.readQueryStringAsMap(argumentsQueryString);
        if (!arguments.isLink(paramName)) {
            throw JsonApplicationException.create(HttpStatusCode.BAD_REQUEST, "Args should contain a link '%s'", paramName);
        }

        return arguments.getLink(paramName).getHref();
    }

}
TOP

Related Classes of org.apache.isis.viewer.json.viewer.resources.domaintypes.DomainTypeResourceServerside

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.