private void addContributeeActionsIfAny( final ObjectAdapter serviceAdapter, final List<ObjectAction> contributeeActionsToAppendTo) { final ObjectSpecification specification = serviceAdapter.getSpecification(); if (specification == this) { return; } final List<ObjectAction> contributeeActions = Lists.newArrayList(); final List<ObjectAction> serviceActions = specification.getObjectActions( ActionType.ALL, Contributed.INCLUDED, Filters.<ObjectAction>any()); for (final ObjectAction serviceAction : serviceActions) { if (isAlwaysHidden(serviceAction)) { continue; } final NotContributedFacet notContributed = serviceAction.getFacet(NotContributedFacet.class); if (notContributed != null && notContributed.toActions()) { continue; } if (!(serviceAction instanceof ObjectActionImpl)) { continue; } final ObjectActionImpl contributedAction = (ObjectActionImpl) serviceAction; // see if qualifies by inspecting all parameters final int contributeeParam = contributeeParameterMatchOf(contributedAction); if (contributeeParam != -1) { ObjectActionContributee contributeeAction = new ObjectActionContributee( serviceAdapter, contributedAction, contributeeParam, this, objectMemberContext); facetProcessor.processMemberOrder(metadataProperties, contributeeAction); contributeeActions.add(contributeeAction); } } contributeeActionsToAppendTo.addAll(contributeeActions); }
private ObjectAction getAction( final List<ObjectAction> availableActions, final ActionType type, final String id) { if (id == null) { return null; } 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, id); if (a != null) { return a; } } else { // regular action if (!type.matchesTypeOf(action)) { continue outer; } if (id.equals(action.getIdentifier().toNameParmsIdentityString())) { return action; } if (id.equals(action.getIdentifier().toNameIdentityString())) { return action; } continue outer; } } return null; }
protected Object homePageIfUsable(ObjectAdapter serviceAdapter, ObjectAction objectAction) { if (!objectAction.containsDoOpFacet(HomePageFacet.class)) { return null; } final Consent visibility = objectAction.isVisible(serviceAdapter, InteractionInitiatedBy.USER, Where.ANYWHERE); if (visibility.isVetoed()) { return null; } final Consent usability = objectAction.isUsable(serviceAdapter, InteractionInitiatedBy.USER, Where.ANYWHERE); if (usability.isVetoed()) { return null; } final ObjectAdapter mixedInAdapter = null; final ObjectAdapter[] parameters = {}; final ObjectAdapter objectAdapter = objectAction.executeWithRuleChecking( serviceAdapter, mixedInAdapter, parameters, InteractionInitiatedBy.USER, WHERE_FOR_ACTION_INVOCATION); return objectAdapter != null ? objectAdapter.getObject() : null; }
private ObjectAction findAction(final ObjectSpecification specification, final String actionId) { final List<ObjectAction> objectActions = specification.getObjectActions(Contributed.INCLUDED); for (final ObjectAction objectAction : objectActions) { if (objectAction.getIdentifier().toClassAndNameIdentityString().equals(actionId)) { return objectAction; } } return null; }
/** * Either creates a link for the action be rendered in a {@link ModalWindow}, or (if none can be * {@link ActionPromptProvider#getActionPrompt() provided}, or creates a link to the {@link * ActionPromptPage} (ie the {@link PageClassRegistry registered page} for {@link * PageType#ACTION_PROMPT action}s). * * <p>If the action's {@link ObjectAction#getSemantics() semantics} are {@link * ActionSemantics.Of#SAFE safe}, then concurrency checking is disabled; otherwise it is enforced. */ protected AbstractLink newLink( final String linkId, final ObjectAdapter objectAdapter, final ObjectAction action, final ActionPromptProvider actionPromptProvider) { final ActionPrompt actionPrompt = actionPromptProvider.getActionPrompt(); if (actionPrompt != null) { final ActionModel actionModel = ActionModel.create(objectAdapter, action); actionModel.setActionPrompt(actionPrompt); AjaxLink<Object> link = new AjaxLink<Object>(linkId) { private static final long serialVersionUID = 1L; @Override public void onClick(AjaxRequestTarget target) { final ActionPanel actionPromptPanel = (ActionPanel) getComponentFactoryRegistry() .createComponent( ComponentType.ACTION_PROMPT, actionPrompt.getContentId(), actionModel); actionPrompt.setPanel(actionPromptPanel, target); actionPrompt.show(target); target.focusComponent(actionPromptPanel); } }; link.add(new CssClassAppender("noVeil")); return link; } else { // use the action semantics to determine whether invoking this action will require a // concurrency check or not // if it's "safe", then we'll just continue without any checking. final ConcurrencyChecking concurrencyChecking = ConcurrencyChecking.concurrencyCheckingFor(action.getSemantics()); final PageParameters pageParameters = ActionModel.createPageParameters(objectAdapter, action, concurrencyChecking); final Class<? extends Page> pageClass = getPageClassRegistry().getPageClass(PageType.ACTION_PROMPT); AbstractLink link = Links.newBookmarkablePageLink(linkId, pageParameters, pageClass); // special case handling if this a no-arg action is returning a URL if (action.getParameterCount() == 0) { addTargetBlankIfActionReturnsUrl(link, action); } return link; } }
Property actionReturnTypeFor(final ObjectAction objectAction) { final ObjectSpecification specification = objectAction.getReturnType(); TypeOfFacet typeOfFacet = objectAction.getFacet(TypeOfFacet.class); if (typeOfFacet != null) { ObjectSpecification elementSpec = typeOfFacet.valueSpec(); if (elementSpec != null) { return arrayPropertyOf(elementSpec); } } return modelFor(specification); }
private void catalogueActions(final Map<Method, ObjectMember> membersByMethod) { final List<ObjectAction> userActions = getObjectActions(ActionType.USER, Contributed.INCLUDED); for (int i = 0; i < userActions.size(); i++) { final ObjectAction userAction = userActions.get(i); final List<Facet> facets = userAction.getFacets(ImperativeFacet.FILTER); for (final Facet facet : facets) { final ImperativeFacet imperativeFacet = ImperativeFacetUtils.getImperativeFacet(facet); for (final Method imperativeFacetMethod : imperativeFacet.getMethods()) { membersByMethod.put(imperativeFacetMethod, userAction); } } } }
private Response invokeActionUsingAdapters( final ObjectAction action, final JsonRepresentation arguments, final ActionResultReprRenderer.SelfLink selfLink) { final RepresentationService.Context rendererContext = representationServiceContext; final ObjectAdapter objectAdapter = this.objectAdapter; final ObjectActionArgHelper argHelper = new ObjectActionArgHelper(rendererContext, objectAdapter, action); final List<ObjectAdapter> argAdapters = argHelper.parseAndValidateArguments(arguments); // invoke final ObjectAdapter mixedInAdapter = null; // action will automatically fill in if a mixin final ObjectAdapter[] argAdapterArr = argAdapters.toArray(new ObjectAdapter[argAdapters.size()]); final ObjectAdapter returnedAdapter = action.execute(objectAdapter, mixedInAdapter, argAdapterArr, InteractionInitiatedBy.USER); final ObjectAndActionInvocation objectAndActionInvocation = new ObjectAndActionInvocation(objectAdapter, action, arguments, returnedAdapter, selfLink); // response transactionService.flushTransaction(); return representationService.actionResult( representationServiceContext, objectAndActionInvocation, selfLink); }
private void addIfReturnsSubtype( final ObjectAction serviceAction, final List<ObjectAction> matchingActionsToAppendTo) { final ObjectSpecification returnType = serviceAction.getReturnType(); if (returnType == null) { return; } if (returnType.isParentedOrFreeCollection()) { final TypeOfFacet facet = serviceAction.getFacet(TypeOfFacet.class); if (facet != null) { final ObjectSpecification elementType = facet.valueSpec(); addIfReturnsSubtype(serviceAction, elementType, matchingActionsToAppendTo); } } else { addIfReturnsSubtype(serviceAction, returnType, matchingActionsToAppendTo); } }
public static void addTargetBlankIfActionReturnsUrl( final AbstractLink link, final ObjectAction action) { final ObjectSpecification returnType = action.getReturnType(); if (returnType != null && "java.net.URL".equals(returnType.getFullIdentifier())) { link.add(new AttributeAppender("target", Model.of("_blank"))); link.add(new CssClassAppender("noVeil")); } }
private void processElement( final Request request, final FormFieldBlock block, final String field) { final String type = request.getOptionalProperty(TYPE, "dropdown"); if (!request.isPropertySpecified(METHOD) && request.isPropertySpecified(COLLECTION)) { final String id = request.getRequiredProperty(COLLECTION, Request.NO_VARIABLE_CHECKING); final String selector = showSelectionList(request, id, block.getCurrent(field), block.isNullable(field), type); block.replaceContent(field, selector); } else { final String objectId = request.getOptionalProperty(OBJECT); final String methodName = request.getRequiredProperty(METHOD); final ObjectAdapter object = MethodsUtils.findObject(request.getContext(), objectId); final ObjectAction action = MethodsUtils.findAction(object, methodName); if (action.getParameterCount() == 0) { final ObjectAdapter collection = action.execute(object, new ObjectAdapter[0]); final String selector = showSelectionList( request, collection, block.getCurrent(field), block.isNullable(field), type); block.replaceContent(field, selector); } else { final String id = "selector_options"; final String id2 = (String) request.getContext().getVariable(id); final String selector = showSelectionList(request, id2, block.getCurrent(field), block.isNullable(field), type); final CreateFormParameter parameters = new CreateFormParameter(); parameters.objectId = objectId; parameters.methodName = methodName; parameters.buttonTitle = request.getOptionalProperty(BUTTON_TITLE, "Search"); parameters.formTitle = request.getOptionalProperty(FORM_TITLE); parameters.className = request.getOptionalProperty(CLASS, "selector"); parameters.id = request.getOptionalProperty(ID); parameters.resultName = id; parameters.forwardResultTo = request.getContext().getResourceFile(); parameters.forwardVoidTo = "error"; parameters.forwardErrorTo = parameters.forwardResultTo; parameters.scope = Scope.REQUEST.name(); request.pushNewBuffer(); ActionForm.createForm(request, parameters); block.replaceContent(field, selector); request.appendHtml(request.popBuffer()); } } }
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; }
/** @param serviceAction - number of the parameter that matches, or -1 if none. */ private int contributeeParameterMatchOf(final ObjectAction serviceAction) { final List<ObjectActionParameter> params = serviceAction.getParameters(); for (final ObjectActionParameter param : params) { if (isOfType(param.getSpecification())) { return param.getNumber(); } } return -1; }
/** * 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 static String roSpecForResponseOf(final ObjectAction action) { final ActionSemantics.Of semantics = action.getSemantics(); switch (semantics) { case SAFE_AND_REQUEST_CACHEABLE: case SAFE: return "19.2"; case IDEMPOTENT: case IDEMPOTENT_ARE_YOU_SURE: return "19.3"; default: return "19.4"; } }
/** * Synthesises {@link ObjectAssociation}s from matching {@link ObjectAction}s of any of the * services that accept one parameter */ private List<ObjectAssociation> createContributeeAssociations( final ObjectAdapter serviceAdapter) { final ObjectSpecification specification = serviceAdapter.getSpecification(); final List<ObjectAction> serviceActions = specification.getObjectActions( ActionType.USER, Contributed.INCLUDED, Filters.<ObjectAction>any()); final List<ObjectActionImpl> contributedActions = Lists.newArrayList(); for (final ObjectAction serviceAction : serviceActions) { if (isAlwaysHidden(serviceAction)) { continue; } final NotContributedFacet notContributed = serviceAction.getFacet(NotContributedFacet.class); if (notContributed != null && notContributed.toAssociations()) { continue; } if (!serviceAction.hasReturn()) { continue; } if (serviceAction.getParameterCount() != 1 || contributeeParameterMatchOf(serviceAction) == -1) { continue; } if (!(serviceAction instanceof ObjectActionImpl)) { continue; } if (!serviceAction.getSemantics().isSafeInNature()) { continue; } contributedActions.add((ObjectActionImpl) serviceAction); } return Lists.newArrayList( Iterables.transform( contributedActions, createContributeeAssociationFunctor(serviceAdapter, this))); }
@SuppressWarnings({"rawtypes"}) private void postEvent( final ObjectAction owningAction, final ObjectAdapter targetAdapter, final ObjectAdapter[] argumentAdapters) { try { final Class type = eventType; Identifier actionIdentifier = owningAction.getIdentifier(); final Object source = AdapterUtils.unwrap(targetAdapter); final Object[] arguments = AdapterUtils.unwrap(argumentAdapters); @SuppressWarnings("unchecked") final ActionInvokedEvent<?> event = org.apache.isis.core.metamodel.facets.actions.event.PostsActionInvokedEventFacet.Util .newEvent(type, source, actionIdentifier, arguments); getEventBusService().post(event); } catch (Exception e) { throw new FatalException(e); } }
// 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))); }
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(); }
public String getNumParams() { return action != null ? "" + action.getParameterCount() : ""; }