You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@isis.apache.org by "Vladimir Nisevic (JIRA)" <ji...@apache.org> on 2014/10/13 22:18:35 UTC

[jira] [Comment Edited] (ISIS-917) Support pluggable representations for the RO viewer (object and list representations)

    [ https://issues.apache.org/jira/browse/ISIS-917?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14169879#comment-14169879 ] 

Vladimir Nisevic edited comment on ISIS-917 at 10/13/14 8:18 PM:
-----------------------------------------------------------------

Hi Dan, once again thank you for this feature. Here my first experience.

I've subclassed the RepresentationServiceForRestfulObjects as advised, but instead of overriding buildResponse I had to override e.g. actionResult method. 
In method "buildResponse" seems to be to late for my requirements?

Then I use Jackson to serialize my entity into JSON. 

Here my code, if you want you could commit it into Todo-App, since it is more concrete example...

{code}
/*
 *  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 webapp;

import dom.todo.ToDoItem;
import dom.todo.ToDoItems;
import org.apache.isis.applib.DomainObjectContainer;
import org.apache.isis.applib.annotation.*;
import org.apache.isis.applib.annotation.ActionSemantics.Of;
import org.apache.isis.applib.services.clock.ClockService;
import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ActionResultReprRenderer;
import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationServiceForRestfulObjects;
import org.codehaus.jackson.map.ObjectMapper;
import org.joda.time.LocalDate;

import javax.ws.rs.core.Response;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

@DomainService
public class ToDoItemsCustomRepresentation extends RepresentationServiceForRestfulObjects {

    @Override
    public Response actionResult(Context rendererContext, ObjectAndActionInvocation objectAndActionInvocation,
                                 ActionResultReprRenderer.SelfLink selfLink) {

        if (objectAndActionInvocation.getAction().getId() == "allToDos") {
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                String writeValueAsString = objectMapper.writeValueAsString(objectAndActionInvocation.getReturnedAdapter().getObject());
                return buildResponse(Response.ok(writeValueAsString));
            } catch (IOException e) {
                e.printStackTrace();
            }
            return buildResponse(Response.serverError());
        }

        return super.actionResult(rendererContext, objectAndActionInvocation, selfLink);
    }

    //region > injected services
    @javax.inject.Inject
    private DomainObjectContainer container;

    @javax.inject.Inject
    private ToDoItems toDoItems;

    //endregion

    //region > helpers
    @javax.inject.Inject
    private ClockService clockService;

    //endregion

    @Prototype
    @ActionSemantics(Of.SAFE)
    @MemberOrder(sequence = "50")
    public List<ToDoItem> allToDos() {
        return toDoItems.allToDos();
    }

    public ToDoItem newToDo(
            final @RegEx(validation = "\\w[@&:\\-\\,\\.\\+ \\w]*") @Named("Description") String description,
            final @Named("Category") ToDoItem.Category category,
            final @Optional @Named("Subcategory") ToDoItem.Subcategory subcategory,
            final @Optional @Named("Due by") LocalDate dueBy,
            final @Optional @Named("Cost") BigDecimal cost) {
        return toDoItems.newToDo(description, category, subcategory, dueBy, cost);
    }
}

{code}

and calling the action allToDos I get now next response. e.g.
{code}
[
-{
description: "bb1"
-dueBy: [
2014
10
27
]
category: "Professional"
subcategory: "OpenSource"
ownedBy: "sven"
complete: false
cost: 3
notes: null
attachment: null
doc: null
dependencies: [ ]
versionSequence: 1
due: true
}
-{
description: "bb1 - Copy"
-dueBy: [
2014
10
27
]
category: "Professional"
subcategory: "OpenSource"
ownedBy: "sven"
complete: false
cost: null
notes: null
attachment: null
doc: null
-dependencies: [
-{
description: "bb1"
-dueBy: [
2014
10
27
]
category: "Professional"
subcategory: "OpenSource"
ownedBy: "sven"
complete: false
cost: 3
notes: null
attachment: null
doc: null
dependencies: [ ]
versionSequence: 1
due: true
}
]
versionSequence: 2
due: true
}
]
{code}

Still have some drawbacks, eg. when calling newTodo, have to POST restful JSON format 

{code}
{
      "description" : {
        "value" : "Test2"
      },
      "category" : {
        "value" : "Professional"
      },
      "subcategory" : {
        "value" : "Education"
      },
      "cost" : {
        "value" : "1"
      }
    }
{code}

would be interesting if I could change that one also to  something like
{code}
{
      "description" : "Test2",
      "category" : "Professional",
      "subcategory" : "Education",
      "cost" : "1"
}
{code}

Anyway many thanks!


was (Author: niv):
Hi Dan, once again thank you for this feature. Here my first experience.

I've subclassed the RepresentationServiceForRestfulObjects as advised, but instead of overriding buildResponse I had to override e.g. actionResult method. 
In method "buildResponse" seems to be to late for my requirements?

Then I use Jackson to serialize my entity into JSON. 

Here my code, if you want you could commit it into Todo-App, since it is more concrete example...

{code}
/*
 *  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 webapp;

import dom.todo.ToDoItem;
import dom.todo.ToDoItems;
import org.apache.isis.applib.DomainObjectContainer;
import org.apache.isis.applib.annotation.*;
import org.apache.isis.applib.annotation.ActionSemantics.Of;
import org.apache.isis.applib.services.clock.ClockService;
import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ActionResultReprRenderer;
import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationServiceForRestfulObjects;
import org.codehaus.jackson.map.ObjectMapper;
import org.joda.time.LocalDate;

import javax.ws.rs.core.Response;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

@DomainService
public class ToDoItemsCustomRepresentation extends RepresentationServiceForRestfulObjects {

    @Override
    public Response actionResult(Context rendererContext, ObjectAndActionInvocation objectAndActionInvocation,
                                 ActionResultReprRenderer.SelfLink selfLink) {

        if (objectAndActionInvocation.getAction().getId() == "allToDos") {
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                String writeValueAsString = objectMapper.writeValueAsString(objectAndActionInvocation.getReturnedAdapter().getObject());
                return buildResponse(Response.ok(writeValueAsString));
            } catch (IOException e) {
                e.printStackTrace();
            }
            return buildResponse(Response.serverError());
        }

        return super.actionResult(rendererContext, objectAndActionInvocation, selfLink);
    }

    //region > injected services
    @javax.inject.Inject
    private DomainObjectContainer container;

    @javax.inject.Inject
    private ToDoItems toDoItems;

    //endregion

    //region > helpers
    @javax.inject.Inject
    private ClockService clockService;

    //endregion

    @Prototype
    @ActionSemantics(Of.SAFE)
    @MemberOrder(sequence = "50")
    public List<ToDoItem> allToDos() {
        return toDoItems.allToDos();
    }

    public ToDoItem newToDo(
            final @RegEx(validation = "\\w[@&:\\-\\,\\.\\+ \\w]*") @Named("Description") String description,
            final @Named("Category") ToDoItem.Category category,
            final @Optional @Named("Subcategory") ToDoItem.Subcategory subcategory,
            final @Optional @Named("Due by") LocalDate dueBy,
            final @Optional @Named("Cost") BigDecimal cost) {
        return toDoItems.newToDo(description, category, subcategory, dueBy, cost);
    }
}

{code]

and calling the action allToDos I get now next response. e.g.
{code}
STATUS 200 OK
TIME 3431 ms
Pretty Raw Preview    JSON Copy
[
-{
description: "bb1"
-dueBy: [
2014
10
27
]
category: "Professional"
subcategory: "OpenSource"
ownedBy: "sven"
complete: false
cost: 3
notes: null
attachment: null
doc: null
dependencies: [ ]
versionSequence: 1
due: true
}
-{
description: "bb1 - Copy"
-dueBy: [
2014
10
27
]
category: "Professional"
subcategory: "OpenSource"
ownedBy: "sven"
complete: false
cost: null
notes: null
attachment: null
doc: null
-dependencies: [
-{
description: "bb1"
-dueBy: [
2014
10
27
]
category: "Professional"
subcategory: "OpenSource"
ownedBy: "sven"
complete: false
cost: 3
notes: null
attachment: null
doc: null
dependencies: [ ]
versionSequence: 1
due: true
}
]
versionSequence: 2
due: true
}
]
{code}

Still have some drawbacks, eg. when calling newTodo, have to POST restful JSON format 

{code}
{
      "description" : {
        "value" : "Test2"
      },
      "category" : {
        "value" : "Professional"
      },
      "subcategory" : {
        "value" : "Education"
      },
      "cost" : {
        "value" : "1"
      }
    }
{code}

would be interesting if I could change that one also to  something like
{code}
{
      "description" : "Test2",
      "category" : "Professional",
      "subcategory" : "Education",
      "cost" : "1"
}
{code}

Anyway many thanks!

> Support pluggable representations for the RO viewer (object and list representations)
> -------------------------------------------------------------------------------------
>
>                 Key: ISIS-917
>                 URL: https://issues.apache.org/jira/browse/ISIS-917
>             Project: Isis
>          Issue Type: New Feature
>          Components: Core: Viewer: RestfulObjects
>    Affects Versions: core-1.6.0
>            Reporter: Dan Haywood
>            Assignee: Dan Haywood
>             Fix For: core-1.7.0
>
>
> This ticket is to factor out the logic in the RO viewer that builds the JSON representation and put it behind a @DomainService.  
> As a first cut, I think it's only the object representation and list representations that need to be pluggable.  
> Ultimately I would like to get to a point where the representation used honours the Accept header (Content-Type), but will probably iterate to get there.  



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)