private static void actionDetails( final ObjectAction objectAction, final int indent, final int count, final DebugBuilder debugBuilder) { debugBuilder.appendln( (count + 1) + "." + objectAction.getId() + " (" + objectAction.getClass().getName() + ")"); debugBuilder.indent(); try { if (objectAction.getDescription() != null && !objectAction.getDescription().equals("")) { debugBuilder.appendln("Description", objectAction.getDescription()); } debugBuilder.appendln("ID", objectAction.getId()); debugBuilder.appendln(objectAction.debugData()); debugBuilder.appendln("On type", objectAction.getOnType()); final Class<? extends Facet>[] facets = objectAction.getFacetTypes(); if (facets.length > 0) { debugBuilder.appendln("Facets"); debugBuilder.indent(); for (final Class<? extends Facet> facet : facets) { debugBuilder.appendln(objectAction.getFacet(facet).toString()); } debugBuilder.unindent(); } final ObjectSpecification returnType = objectAction.getReturnType(); debugBuilder.appendln("Returns", returnType == null ? "VOID" : returnType.toString()); final List<ObjectActionParameter> parameters = objectAction.getParameters(); if (parameters.size() == 0) { debugBuilder.appendln("Parameters", "none"); } else { debugBuilder.appendln("Parameters"); debugBuilder.indent(); final List<ObjectActionParameter> p = objectAction.getParameters(); for (int j = 0; j < parameters.size(); j++) { debugBuilder.append(p.get(j).getName()); debugBuilder.append(" ("); debugBuilder.append(parameters.get(j).getSpecification().getFullIdentifier()); debugBuilder.appendln(")"); debugBuilder.indent(); final Class<? extends Facet>[] parameterFacets = p.get(j).getFacetTypes(); for (final Class<? extends Facet> parameterFacet : parameterFacets) { debugBuilder.appendln(p.get(j).getFacet(parameterFacet).toString()); } debugBuilder.unindent(); } debugBuilder.unindent(); } } catch (final RuntimeException e) { debugBuilder.appendException(e); } debugBuilder.unindent(); }
private ObjectAction getAction( final List<ObjectAction> availableActions, final ActionType type, final String actionName, final List<ObjectSpecification> parameters) { outer: for (int i = 0; i < availableActions.size(); i++) { final ObjectAction action = availableActions.get(i); if (action.getActions().size() > 0) { // deal with action set final ObjectAction a = getAction(action.getActions(), type, actionName, parameters); if (a != null) { return a; } } else { // regular action if (!action.getType().equals(type)) { continue outer; } if (actionName != null && !actionName.equals(action.getId())) { continue outer; } if (action.getParameters().size() != parameters.size()) { continue outer; } for (int j = 0; j < parameters.size(); j++) { if (!parameters.get(j).isOfType(action.getParameters().get(j).getSpecification())) { continue outer; } } return action; } } return null; }
/** * Invokes the action for the object (checking it is visible) and then delegates to the {@link * org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService} to render a * representation of the result of that action. * * <p>The action must have {@link org.apache.isis.applib.annotation.ActionSemantics.Of#IDEMPOTENT * idempotent} semantics otherwise an error response is thrown. */ public Response invokeActionIdempotent( final String actionId, final JsonRepresentation arguments) { final ObjectAdapterAccessHelper accessHelper = new ObjectAdapterAccessHelper(representationServiceContext, objectAdapter); final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent( actionId, ObjectAdapterAccessHelper.Intent.MUTATE); final ActionSemantics.Of actionSemantics = action.getSemantics(); if (!actionSemantics.isIdempotentInNature()) { throw RestfulObjectsApplicationException.createWithMessage( RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Method not allowed; action '%s' is not idempotent", action.getId()); } return invokeActionUsingAdapters(action, arguments, ActionResultReprRenderer.SelfLink.EXCLUDED); }
// UNUSED void appendServiceActionPromptTo(final ObjectProperty serviceMembers, final ObjectAction action) { String actionId = action.getId(); serviceMembers.property( actionId, new ObjectProperty() .property("id", stringPropertyEnum(actionId)) .property("memberType", stringPropertyEnum("action")) .property( "links", new ObjectProperty() .property( "rel", stringPropertyEnum( String.format( "urn:org.restfulobjects:rels/details;action=%s", actionId))) .property("href", stringPropertyEnum(String.format("actions/%s", actionId)))) .property("method", stringPropertyEnum("GET")) .property( "type", stringPropertyEnum( "application/json;profile=urn:org.restfulobjects:repr-types/object-action"))); }
void appendObjectActionInvokePath( final ObjectSpecification objectSpec, final ObjectAction objectAction) { final String objectType = objectTypeFor(objectSpec); final String actionId = objectAction.getId(); final List<ObjectActionParameter> parameters = objectAction.getParameters(); final Path path = new Path(); swagger.path( String.format("/objects/%s/{objectId}/actions/%s/invoke", objectType, actionId), path); final String tag = tagFor(objectType, null); final Operation invokeOperation = new Operation() .tag(tag) .description( Util.roSpec("19.1") + ": (invoke) resource of " + objectType + "#" + actionId) .parameter(new PathParameter().name("objectId").type("string")) .produces("application/json;profile=urn:org.apache.isis/v1") .produces("application/json;profile=urn:org.apache.isis/v1;suppress=true") .produces("application/json;profile=urn:org.restfulobjects:repr-types/action-result"); final ActionSemantics.Of semantics = objectAction.getSemantics(); if (semantics.isSafeInNature()) { path.get(invokeOperation); for (final ObjectActionParameter parameter : parameters) { invokeOperation.parameter( new QueryParameter() .name(parameter.getId()) .description( Util.roSpec("2.9.1") + (!Strings.isNullOrEmpty(parameter.getDescription()) ? (": " + parameter.getDescription()) : "")) .required(false) .type("string")); } if (!parameters.isEmpty()) { invokeOperation.parameter( new QueryParameter() .name("x-isis-querystring") .description( Util.roSpec("2.10") + ": all (formal) arguments as base64 encoded string") .required(false) .type("string")); } } else { if (semantics.isIdempotentInNature()) { path.put(invokeOperation); } else { path.post(invokeOperation); } final ModelImpl bodyParam = new ModelImpl().type("object"); for (final ObjectActionParameter parameter : parameters) { final ObjectSpecification specification = parameter.getSpecification(); final Property valueProperty = specification.isValue() ? modelFor(specification) : refToLinkModel(); bodyParam.property( parameter.getId(), new ObjectProperty().property("value", valueProperty)); } invokeOperation .consumes("application/json") .parameter(new BodyParameter().name("body").schema(bodyParam)); } invokeOperation.response( 200, new Response() .description(objectType + "#" + actionId) .schema(actionReturnTypeFor(objectAction))); }
void appendServiceActionInvokePath( final ObjectSpecification serviceSpec, final ObjectAction serviceAction) { final String serviceId = serviceIdFor(serviceSpec); final String actionId = serviceAction.getId(); final List<ObjectActionParameter> parameters = serviceAction.getParameters(); final Path path = new Path(); swagger.path(String.format("/services/%s/actions/%s/invoke", serviceId, actionId), path); final String tag = tagFor(serviceId, "> services"); final Operation invokeOperation = new Operation() .tag(tag) .description( Util.roSpec("19.1") + ": (invoke) resource of " + serviceId + "#" + actionId) .produces("application/json;profile=urn:org.apache.isis/v1") .produces("application/json;profile=urn:org.apache.isis/v1;suppress=true") .produces("application/json;profile=urn:org.restfulobjects:repr-types/action-result"); final ActionSemantics.Of semantics = serviceAction.getSemantics(); if (semantics.isSafeInNature()) { path.get(invokeOperation); for (final ObjectActionParameter parameter : parameters) { invokeOperation.parameter( new QueryParameter() .name(parameter.getId()) .description( Util.roSpec("2.9.1") + (!Strings.isNullOrEmpty(parameter.getDescription()) ? (": " + parameter.getDescription()) : "")) .required(false) .type("string")); } if (!parameters.isEmpty()) { invokeOperation.parameter( new QueryParameter() .name("x-isis-querystring") .description( Util.roSpec("2.10") + ": all (formal) arguments as base64 encoded string") .required(false) .type("string")); } } else { if (semantics.isIdempotentInNature()) { path.put(invokeOperation); } else { path.post(invokeOperation); } final ModelImpl bodyParam = new ModelImpl().type("object"); for (final ObjectActionParameter parameter : parameters) { final Property valueProperty; // TODO: need to switch on parameter's type and create appropriate impl of valueProperty // if(parameter.getSpecification().isValue()) ... valueProperty = stringProperty(); bodyParam.property( parameter.getId(), new ObjectProperty().property("value", valueProperty)); } invokeOperation .consumes("application/json") .parameter(new BodyParameter().name("body").schema(bodyParam)); } invokeOperation.response( 200, new Response() .description( serviceId + "#" + actionId + " , if Accept: application/json;profile=urn:org.apache.isis/v1") .schema(actionReturnTypeFor(serviceAction))); }