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.domainobjects; 021 022import java.util.List; 023import java.util.Map; 024import com.fasterxml.jackson.databind.node.NullNode; 025import org.apache.isis.applib.annotation.SemanticsOf; 026import org.apache.isis.applib.annotation.Where; 027import org.apache.isis.commons.internal.collections._Lists; 028import org.apache.isis.commons.internal.collections._Maps; 029import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy; 030import org.apache.isis.core.metamodel.interactions.managed.ManagedAction; 031import org.apache.isis.core.metamodel.spec.ManagedObjects; 032import org.apache.isis.core.metamodel.spec.feature.ObjectAction; 033import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter; 034import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation; 035import org.apache.isis.viewer.restfulobjects.applib.Rel; 036import org.apache.isis.viewer.restfulobjects.applib.RepresentationType; 037import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext; 038import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs; 039import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.ActionDescriptionReprRenderer; 040 041public class ObjectActionReprRenderer extends AbstractObjectMemberReprRenderer<ObjectActionReprRenderer, ObjectAction> { 042 public ObjectActionReprRenderer(IResourceContext resourceContext) { 043 this(resourceContext, null, null, JsonRepresentation.newMap()); 044 } 045 046 public ObjectActionReprRenderer(final IResourceContext resourceContext, final LinkFollowSpecs linkFollowSpecs, String actionId, final JsonRepresentation representation) { 047 super(resourceContext, linkFollowSpecs, actionId, RepresentationType.OBJECT_ACTION, representation, Where.OBJECT_FORMS); 048 } 049 050 @Override 051 public JsonRepresentation render() { 052 renderMemberContent(); 053 putDisabledReasonIfDisabled(); 054 if (mode.isStandalone() || mode.isMutated()) { 055 addParameterDetails(); 056 } 057 return representation; 058 } 059 060 // /////////////////////////////////////////////////// 061 // details link 062 // /////////////////////////////////////////////////// 063 /** 064 * Mandatory hook method to support x-ro-follow-links 065 */ 066 @Override 067 protected void followDetailsLink(final JsonRepresentation detailsLink) { 068 final org.apache.isis.applib.annotation.Where where = resourceContext.getWhere(); 069 final ObjectActionReprRenderer renderer = new ObjectActionReprRenderer(getResourceContext(), getLinkFollowSpecs(), null, JsonRepresentation.newMap()); 070 renderer.with(ManagedAction.of(objectAdapter, objectMember, where)).usingLinkTo(linkTo).asFollowed(); 071 detailsLink.mapPut("value", renderer.render()); 072 } 073 074 // /////////////////////////////////////////////////// 075 // mutators 076 // /////////////////////////////////////////////////// 077 @Override 078 protected void addMutatorLinksIfEnabled() { 079 if (usability().isVetoed()) { 080 return; 081 } 082 final Map<String, MutatorSpec> mutators = objectMemberType.getMutators(); 083 final SemanticsOf actionSemantics = objectMember.getSemantics(); 084 final String mutator = InvokeKeys.getKeyFor(actionSemantics); 085 final MutatorSpec mutatorSpec = mutators.get(mutator); 086 addLinkFor(mutatorSpec); 087 } 088 089 @Override 090 protected ObjectAdapterLinkTo linkToForMutatorInvoke() { 091 return super.linkToForMutatorInvoke(); 092 } 093 094 @Override 095 protected JsonRepresentation mutatorArgs(final MutatorSpec mutatorSpec) { 096 final JsonRepresentation argMap = JsonRepresentation.newMap(); 097 final org.apache.isis.commons.collections.Can<org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter> parameters = objectMember.getParameters(); 098 for (int i = 0; i < objectMember.getParameterCount(); i++) { 099 argMap.mapPut(parameters.getElseFail(i).getId() + ".value", argValueFor(i)); 100 } 101 return argMap; 102 } 103 104 private Object argValueFor(final int i) { 105 // force a null into the map 106 return NullNode.getInstance(); 107 } 108 109 // /////////////////////////////////////////////////// 110 // parameter details 111 // /////////////////////////////////////////////////// 112 private ObjectActionReprRenderer addParameterDetails() { 113 final Map<String, Object> parameters = _Maps.newLinkedHashMap(); 114 for (int i = 0; i < objectMember.getParameterCount(); i++) { 115 final ObjectActionParameter param = objectMember.getParameters().getElseFail(i); 116 final Object paramDetails = paramDetails(param, getInteractionInitiatedBy()); 117 parameters.put(param.getId(), paramDetails); 118 } 119 representation.mapPut("parameters", parameters); 120 return this; 121 } 122 123 private Object paramDetails(final ObjectActionParameter param, final InteractionInitiatedBy interactionInitiatedBy) { 124 final JsonRepresentation paramRep = JsonRepresentation.newMap(); 125 paramRep.mapPut("num", param.getNumber()); 126 paramRep.mapPut("id", param.getId()); 127 paramRep.mapPut("name", param.getName()); 128 paramRep.mapPut("description", param.getDescription()); 129 final Object paramChoices = choicesFor(param, interactionInitiatedBy); 130 if (paramChoices != null) { 131 paramRep.mapPut("choices", paramChoices); 132 } 133 final Object paramDefault = defaultFor(param); 134 if (paramDefault != null) { 135 paramRep.mapPut("default", paramDefault); 136 } 137 return paramRep; 138 } 139 140 private Object choicesFor(final ObjectActionParameter param, final InteractionInitiatedBy interactionInitiatedBy) { 141 final org.apache.isis.core.metamodel.interactions.managed.ParameterNegotiationModel pendingArgs = param.getAction().interactionHead(objectAdapter).emptyModel(); 142 final org.apache.isis.commons.collections.Can<org.apache.isis.core.metamodel.spec.ManagedObject> choiceAdapters = param.getChoices(pendingArgs, interactionInitiatedBy); 143 if (choiceAdapters == null || choiceAdapters.isEmpty()) { 144 return null; 145 } 146 final List<Object> list = _Lists.newArrayList(); 147 for (final org.apache.isis.core.metamodel.spec.ManagedObject choiceAdapter : choiceAdapters) { 148 // REVIEW: previously was using the spec of the parameter, but think instead it should be the spec of the adapter itself 149 // final ObjectSpecification choiceSpec = param.getSpecification(); 150 list.add(DomainObjectReprRenderer.valueOrRef(resourceContext, super.getJsonValueEncoder(), choiceAdapter)); 151 } 152 return list; 153 } 154 155 private Object defaultFor(final ObjectActionParameter param) { 156 final org.apache.isis.core.metamodel.interactions.managed.ParameterNegotiationModel emptyPpm = param.getAction().interactionHead(objectAdapter).emptyModel(); 157 final org.apache.isis.core.metamodel.spec.ManagedObject defaultAdapter = param.getDefault(emptyPpm); 158 if (ManagedObjects.isNullOrUnspecifiedOrEmpty(defaultAdapter)) { 159 return null; 160 } 161 // REVIEW: previously was using the spec of the parameter, but think instead it should be the spec of the adapter itself 162 // final ObjectSpecification defaultSpec = param.getSpecification(); 163 return DomainObjectReprRenderer.valueOrRef(resourceContext, super.getJsonValueEncoder(), defaultAdapter); 164 } 165 166 // /////////////////////////////////////////////////// 167 // extensions and links 168 // /////////////////////////////////////////////////// 169 @Override 170 protected void addLinksToFormalDomainModel() { 171 if (resourceContext.suppressDescribedByLinks()) { 172 return; 173 } 174 final JsonRepresentation link = ActionDescriptionReprRenderer.newLinkToBuilder(resourceContext, Rel.DESCRIBEDBY, objectAdapter.getSpecification(), objectMember).build(); 175 getLinks().arrayAdd(link); 176 } 177 178 @Override 179 protected void putExtensionsIsisProprietary() { 180 getExtensions().mapPut("actionType", objectMember.getType().name().toLowerCase()); 181 final SemanticsOf semantics = objectMember.getSemantics(); 182 getExtensions().mapPut("actionSemantics", semantics.getCamelCaseName()); 183 } 184}