You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2018/02/28 12:38:31 UTC

[isis] branch maint-1.16.2 updated (b2d720f -> bc7253b)

This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a change to branch maint-1.16.2
in repository https://gitbox.apache.org/repos/asf/isis.git.


    from b2d720f  ISIS-1884: restricts contribution of choices and default only if @Action(associatedWith) is used...
     new d6fddad  ISIS-1882: adds DomainObjectList, special cases support within JaxbServiceDefault, adds support for new Accept type for action invocation.
     new 90b05d4  ISIS-1882: moves DomainObjectList into new package, use objectType rather than FQCN for the element type, and adds domain events etc.
     new 236adc8  ISIS-1882: handles case when action result returns a single adapter, not a collection
     new b0d3b6e  ISIS-1882: updates to docs
     new 804f103  ISIS-1882: extends DomainObjectList to contain details of the action invocation.
     new bc7253b  Merge branch 'ISIS-1882' into maint-1.16.2

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 ...esentation-layer_ContentNegotiationService.adoc |  10 +-
 .../org/apache/isis/applib/IsisApplibModule.java   |  13 ++
 .../isis/applib/domain/DomainObjectList.java       | 176 +++++++++++++++++++++
 .../isis/applib/services/jaxb/JaxbService.java     |  45 ++++--
 .../schema/services/jaxb/JaxbServiceDefault.java   |  70 +++++++-
 ...Adapter.java => PersistentEntitiesAdapter.java} |  33 ++--
 .../services/swagger/internal/Generation.java      |   1 +
 .../domainobjects/ObjectAndActionInvocation.java   |   9 ++
 ...entNegotiationServiceForRestfulObjectsV1_0.java | 174 ++++++++++++++++++--
 .../server/resources/DomainResourceHelper.java     |   2 +-
 10 files changed, 486 insertions(+), 47 deletions(-)
 create mode 100644 core/applib/src/main/java/org/apache/isis/applib/domain/DomainObjectList.java
 copy core/applib/src/main/java/org/apache/isis/schema/utils/jaxbadapters/{PersistentEntityAdapter.java => PersistentEntitiesAdapter.java} (59%)

-- 
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.

[isis] 06/06: Merge branch 'ISIS-1882' into maint-1.16.2

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch maint-1.16.2
in repository https://gitbox.apache.org/repos/asf/isis.git

commit bc7253b32a29aba390bd18ebe09e492858414e9c
Merge: b2d720f 804f103
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Feb 28 12:34:38 2018 +0000

    Merge branch 'ISIS-1882' into maint-1.16.2

 ...esentation-layer_ContentNegotiationService.adoc |  10 +-
 .../org/apache/isis/applib/IsisApplibModule.java   |  13 ++
 .../isis/applib/domain/DomainObjectList.java       | 176 +++++++++++++++++++++
 .../isis/applib/services/jaxb/JaxbService.java     |  45 ++++--
 .../schema/services/jaxb/JaxbServiceDefault.java   |  70 +++++++-
 .../jaxbadapters/PersistentEntitiesAdapter.java    |  70 ++++++++
 .../services/swagger/internal/Generation.java      |   1 +
 .../domainobjects/ObjectAndActionInvocation.java   |   9 ++
 ...entNegotiationServiceForRestfulObjectsV1_0.java | 174 ++++++++++++++++++--
 .../server/resources/DomainResourceHelper.java     |   2 +-
 10 files changed, 533 insertions(+), 37 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.

[isis] 02/06: ISIS-1882: moves DomainObjectList into new package, use objectType rather than FQCN for the element type, and adds domain events etc.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch maint-1.16.2
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 90b05d411150032b7f9827c5ea58e6cd7ed02373
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Feb 28 11:02:50 2018 +0000

    ISIS-1882: moves DomainObjectList into new package, use objectType rather than FQCN for the element type, and adds domain events etc.
---
 .../org/apache/isis/applib/IsisApplibModule.java   |  13 +++
 .../isis/applib/domain/DomainObjectList.java       | 119 +++++++++++++++++++++
 .../applib/services/jaxb/DomainObjectList.java     |  59 ----------
 .../isis/applib/services/jaxb/JaxbService.java     |  31 ++----
 .../schema/services/jaxb/JaxbServiceDefault.java   |  51 +++++++++
 ...entNegotiationServiceForRestfulObjectsV1_0.java |   4 +-
 6 files changed, 192 insertions(+), 85 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/IsisApplibModule.java b/core/applib/src/main/java/org/apache/isis/applib/IsisApplibModule.java
index d259ce5..20771a0 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/IsisApplibModule.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/IsisApplibModule.java
@@ -25,6 +25,16 @@ import javax.xml.bind.annotation.XmlRootElement;
 @XmlRootElement(name = "module")
 public class IsisApplibModule extends ModuleAbstract {
 
+    //region > ui event classes
+    public abstract static class TitleUiEvent<S>
+            extends org.apache.isis.applib.services.eventbus.TitleUiEvent<S> { }
+    public abstract static class IconUiEvent<S>
+            extends org.apache.isis.applib.services.eventbus.IconUiEvent<S> { }
+    public abstract static class CssClassUiEvent<S>
+            extends org.apache.isis.applib.services.eventbus.CssClassUiEvent<S> { }
+    //endregion
+
+    //region > domain event classes
     public abstract static class ActionDomainEvent<S> extends org.apache.isis.applib.services.eventbus.ActionDomainEvent<S> {
         public ActionDomainEvent() {}
 
@@ -86,4 +96,7 @@ public class IsisApplibModule extends ModuleAbstract {
             super(source, identifier, oldValue, newValue);
         }
     }
+
+    //endregion
+
 }
diff --git a/core/applib/src/main/java/org/apache/isis/applib/domain/DomainObjectList.java b/core/applib/src/main/java/org/apache/isis/applib/domain/DomainObjectList.java
new file mode 100644
index 0000000..9b7a41c
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/domain/DomainObjectList.java
@@ -0,0 +1,119 @@
+/**
+ *  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.applib.domain;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.IsisApplibModule;
+import org.apache.isis.applib.annotation.Collection;
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.DomainObjectLayout;
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Nature;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.schema.utils.jaxbadapters.PersistentEntitiesAdapter;
+
+@XmlRootElement(name = "list")
+@XmlType(
+        propOrder = {
+                "title",
+                "elementObjectType",
+                "objects"
+        }
+)
+@XmlAccessorType(XmlAccessType.FIELD)
+@DomainObject(
+        objectType = "isisApplib.DomainObjectList",
+        editing = Editing.DISABLED,
+        nature = Nature.VIEW_MODEL
+)
+@DomainObjectLayout(
+        titleUiEvent = DomainObjectList.TitleUiEvent.class,
+        iconUiEvent = DomainObjectList.IconUiEvent.class,
+        cssClassUiEvent = DomainObjectList.CssClassUiEvent.class
+)
+public class DomainObjectList {
+
+    //region > ui event classes
+    public static class TitleUiEvent extends IsisApplibModule.TitleUiEvent<DomainObjectList>{}
+    public static class IconUiEvent extends IsisApplibModule.IconUiEvent<DomainObjectList>{}
+    public static class CssClassUiEvent extends IsisApplibModule.CssClassUiEvent<DomainObjectList>{}
+    //endregion
+
+    //region > domain event classes
+    public static abstract class PropertyDomainEvent<T> extends IsisApplibModule.PropertyDomainEvent<DomainObjectList, T> { }
+    public static abstract class CollectionDomainEvent<T> extends IsisApplibModule.CollectionDomainEvent<DomainObjectList, T> { }
+    public static abstract class ActionDomainEvent extends IsisApplibModule.ActionDomainEvent<DomainObjectList> { }
+    //endregion
+
+    //region > constructors
+    public DomainObjectList() {
+    }
+    public DomainObjectList(final String title, final String elementObjectType) {
+        this.title = title;
+        this.elementObjectType = elementObjectType;
+    }
+    //endregion
+
+    //region > title
+    private String title;
+    public String title() {
+        return title;
+    }
+    //endregion
+
+    //region > property: elementObjectType
+    public static class ElementObjectTypeDomainEvent extends PropertyDomainEvent<String> { }
+
+    private String elementObjectType;
+    @Property(
+            domainEvent = ElementObjectTypeDomainEvent.class,
+            editing = Editing.DISABLED
+    )
+    public String getElementObjectType() {
+        return elementObjectType;
+    }
+    //endregion
+
+    //region > collection: objects
+    public static class ObjectsDomainEvent extends CollectionDomainEvent<Object> { }
+
+    @XmlJavaTypeAdapter(PersistentEntitiesAdapter.class)
+    private List<Object> objects = Lists.newArrayList();
+
+    @Collection(
+            domainEvent = ObjectsDomainEvent.class,
+            editing = Editing.DISABLED
+    )
+    public List<Object> getObjects() {
+        return objects;
+    }
+
+    public void setObjects(final List<Object> objects) {
+        this.objects = objects;
+    }
+    //endregion
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/DomainObjectList.java b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/DomainObjectList.java
deleted file mode 100644
index b30ad3c..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/DomainObjectList.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.apache.isis.applib.services.jaxb;
-
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-
-import com.google.common.collect.Lists;
-
-import org.apache.isis.applib.annotation.Collection;
-import org.apache.isis.applib.annotation.Editing;
-import org.apache.isis.applib.annotation.Property;
-import org.apache.isis.schema.utils.jaxbadapters.PersistentEntitiesAdapter;
-
-@XmlRootElement(name = "list")
-@XmlType(
-        propOrder = {
-                "title",
-                "elementType",
-                "objects"
-        }
-)
-@XmlAccessorType(XmlAccessType.FIELD)
-public class DomainObjectList {
-
-    public DomainObjectList() {
-    }
-    public DomainObjectList(final String title, final Class<?> elementType) {
-        this.title = title;
-        this.elementType = elementType.getCanonicalName();
-    }
-
-    private String title;
-    public String title() { return title; }
-
-    private String elementType;
-    @Property(editing = Editing.DISABLED)
-    public String getElementType() {
-        return elementType;
-    }
-
-
-    @XmlJavaTypeAdapter(PersistentEntitiesAdapter.class)
-    private List<Object> objects = Lists.newArrayList();
-
-    @Collection(editing = Editing.DISABLED)
-    public List<Object> getObjects() {
-        return objects;
-    }
-
-    public void setObjects(final List<Object> objects) {
-        this.objects = objects;
-    }
-
-}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
index b028893..f5681b1 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
@@ -105,28 +105,19 @@ public interface JaxbService {
         public Object fromXml(final JAXBContext jaxbContext, final String xml) {
             return fromXml(jaxbContext, xml, Maps.<String,Object>newHashMap());
         }
+
         @Override
         public Object fromXml(final JAXBContext jaxbContext, final String xml, final Map<String, Object> unmarshallerProperties) {
             try {
 
-                Object unmarshal = internalFromXml(jaxbContext, xml, unmarshallerProperties);
-
-                if(unmarshal instanceof DomainObjectList) {
-
-                    // go around the loop again, so can properly deserialize the contents
-                    DomainObjectList domainObjectList = (DomainObjectList) unmarshal;
-                    JAXBContext jaxbContext1 = jaxbContextFor(domainObjectList);
-                    unmarshal = internalFromXml(jaxbContext1, xml, unmarshallerProperties);
-                }
-
-                return unmarshal;
+                return internalFromXml(jaxbContext, xml, unmarshallerProperties);
 
             } catch (final JAXBException ex) {
                 throw new NonRecoverableException("Error unmarshalling XML", ex);
             }
         }
 
-        private Object internalFromXml(
+        protected Object internalFromXml(
                 final JAXBContext jaxbContext,
                 final String xml,
                 final Map<String, Object> unmarshallerProperties) throws JAXBException {
@@ -222,21 +213,13 @@ public interface JaxbService {
             }
         }
 
-        private static JAXBContext jaxbContextFor(final Object domainObject) {
+        /**
+         * Optional hook
+         */
+        protected JAXBContext jaxbContextFor(final Object domainObject) {
             final Class<?> domainClass = domainObject.getClass();
             final JAXBContext context;
-            if(domainObject instanceof DomainObjectList) {
-                DomainObjectList list = (DomainObjectList) domainObject;
-                final Class<?> elementType;
-                try {
-                    elementType = Thread.currentThread().getContextClassLoader().loadClass(list.getElementType());
-                    context = JAXBContext.newInstance(domainClass, elementType);
-                } catch (JAXBException | ClassNotFoundException e) {
-                    throw new RuntimeException(e);
-                }
-            } else {
                 context = jaxbContextFor(domainClass);
-            }
             return context;
         }
 
diff --git a/core/applib/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java b/core/applib/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java
index 0537d10..abcef48 100644
--- a/core/applib/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java
+++ b/core/applib/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java
@@ -16,12 +16,19 @@
  */
 package org.apache.isis.schema.services.jaxb;
 
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
 
+import org.apache.isis.applib.NonRecoverableException;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.domain.DomainObjectList;
 import org.apache.isis.applib.services.jaxb.JaxbService;
+import org.apache.isis.applib.services.metamodel.MetaModelService5;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.schema.utils.jaxbadapters.PersistentEntitiesAdapter;
 import org.apache.isis.schema.utils.jaxbadapters.PersistentEntityAdapter;
@@ -32,6 +39,45 @@ import org.apache.isis.schema.utils.jaxbadapters.PersistentEntityAdapter;
 )
 public class JaxbServiceDefault extends JaxbService.Simple {
 
+    @Override
+    public Object fromXml(final JAXBContext jaxbContext, final String xml, final Map<String, Object> unmarshallerProperties) {
+        try {
+            Object pojo = internalFromXml(jaxbContext, xml, unmarshallerProperties);
+
+            if(pojo instanceof DomainObjectList) {
+
+                // go around the loop again, so can properly deserialize the contents
+                DomainObjectList list = (DomainObjectList) pojo;
+                JAXBContext jaxbContextForList = jaxbContextFor(list);
+                
+                return internalFromXml(jaxbContextForList, xml, unmarshallerProperties);
+            }
+
+            return pojo;
+
+        } catch (final JAXBException ex) {
+            throw new NonRecoverableException("Error unmarshalling XML", ex);
+        }
+    }
+
+    @Override
+    protected JAXBContext jaxbContextFor(final Object domainObject) {
+        final Class<?> domainClass = domainObject.getClass();
+        if(domainObject instanceof DomainObjectList) {
+            DomainObjectList list = (DomainObjectList) domainObject;
+            try {
+                final String elementObjectType = list.getElementObjectType();
+                final Class<?> elementType = metaModelService5.fromObjectType(elementObjectType);
+                return JAXBContext.newInstance(domainClass, elementType);
+            } catch (JAXBException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        return super.jaxbContextFor(domainObject);
+    }
+
+
+    @Override
     protected void configure(final Unmarshaller unmarshaller) {
         unmarshaller.setAdapter(PersistentEntityAdapter.class,
                 serviceRegistry.injectServicesInto(new PersistentEntityAdapter()));
@@ -39,6 +85,7 @@ public class JaxbServiceDefault extends JaxbService.Simple {
                 serviceRegistry.injectServicesInto(new PersistentEntitiesAdapter()));
     }
 
+    @Override
     protected void configure(final Marshaller marshaller) {
         marshaller.setAdapter(PersistentEntityAdapter.class,
                 serviceRegistry.injectServicesInto(new PersistentEntityAdapter()));
@@ -46,7 +93,11 @@ public class JaxbServiceDefault extends JaxbService.Simple {
                 serviceRegistry.injectServicesInto(new PersistentEntitiesAdapter()));
     }
 
+
     @javax.inject.Inject
     ServiceRegistry serviceRegistry;
+
+    @javax.inject.Inject
+    MetaModelService5 metaModelService5;
 }
 
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
index dc124c6..30adc0a 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -30,7 +30,7 @@ import javax.ws.rs.core.Response.ResponseBuilder;
 
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.applib.services.jaxb.DomainObjectList;
+import org.apache.isis.applib.domain.DomainObjectList;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.version.Version;
 import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
@@ -231,7 +231,7 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
 
         final String title = titleFrom(collectionAdapters, elementSpec);
 
-        final DomainObjectList list = new DomainObjectList(title, elementSpec.getCorrespondingClass());
+        final DomainObjectList list = new DomainObjectList(title, elementSpec.getSpecId().asString());
         for (final ObjectAdapter adapter : collectionAdapters) {
             list.getObjects().add(adapter.getObject());
         }

-- 
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.

[isis] 05/06: ISIS-1882: extends DomainObjectList to contain details of the action invocation.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch maint-1.16.2
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 804f103b0a1852a5a4cf20953e8142b3a0de9254
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Feb 28 12:34:22 2018 +0000

    ISIS-1882: extends DomainObjectList to contain details of the action invocation.
---
 .../isis/applib/domain/DomainObjectList.java       | 59 +++++++++++++++++++++-
 .../domainobjects/ObjectAndActionInvocation.java   |  9 ++++
 ...entNegotiationServiceForRestfulObjectsV1_0.java | 49 ++++++++++++++++--
 .../server/resources/DomainResourceHelper.java     |  2 +-
 4 files changed, 114 insertions(+), 5 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/domain/DomainObjectList.java b/core/applib/src/main/java/org/apache/isis/applib/domain/DomainObjectList.java
index 9b7a41c..34e485b 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/domain/DomainObjectList.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/domain/DomainObjectList.java
@@ -32,6 +32,7 @@ import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainObjectLayout;
 import org.apache.isis.applib.annotation.Editing;
 import org.apache.isis.applib.annotation.Nature;
+import org.apache.isis.applib.annotation.Optionality;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.schema.utils.jaxbadapters.PersistentEntitiesAdapter;
 
@@ -39,6 +40,9 @@ import org.apache.isis.schema.utils.jaxbadapters.PersistentEntitiesAdapter;
 @XmlType(
         propOrder = {
                 "title",
+                "actionOwningType",
+                "actionId",
+                "actionArguments",
                 "elementObjectType",
                 "objects"
         }
@@ -71,9 +75,17 @@ public class DomainObjectList {
     //region > constructors
     public DomainObjectList() {
     }
-    public DomainObjectList(final String title, final String elementObjectType) {
+    public DomainObjectList(
+            final String title,
+            final String elementObjectType,
+            final String actionOwningType,
+            final String actionId,
+            final String actionArguments) {
         this.title = title;
         this.elementObjectType = elementObjectType;
+        this.actionOwningType = actionOwningType;
+        this.actionId = actionId;
+        this.actionArguments = actionArguments;
     }
     //endregion
 
@@ -97,6 +109,51 @@ public class DomainObjectList {
     }
     //endregion
 
+    //region > property: actionOwningType
+    public static class ActionOwningTypeDomainEvent extends PropertyDomainEvent<String> { }
+
+    private String actionOwningType;
+
+    @Property(
+            domainEvent = ActionOwningTypeDomainEvent.class,
+            optionality = Optionality.OPTIONAL,
+            editing = Editing.DISABLED
+    )
+    public String getActionOwningType() {
+        return actionOwningType;
+    }
+    //endregion
+
+    //region > property: actionId
+    public static class ActionIdDomainEvent extends PropertyDomainEvent<String> { }
+
+    private String actionId;
+
+    @Property(
+            domainEvent = ActionIdDomainEvent.class,
+            optionality = Optionality.OPTIONAL,
+            editing = Editing.DISABLED
+    )
+    public String getActionId() {
+        return actionId;
+    }
+    //endregion
+
+    //region > property: actionArguments
+    public static class ActionArgumentsDomainEvent extends PropertyDomainEvent<String> { }
+
+    private String actionArguments;
+
+    @Property(
+            domainEvent = ActionArgumentsDomainEvent.class,
+            optionality = Optionality.OPTIONAL,
+            editing = Editing.DISABLED
+    )
+    public String getActionArguments() {
+        return actionArguments;
+    }
+    //endregion
+
     //region > collection: objects
     public static class ObjectsDomainEvent extends CollectionDomainEvent<Object> { }
 
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
index f009d3f..70b695e 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
@@ -18,6 +18,8 @@
  */
 package org.apache.isis.viewer.restfulobjects.rendering.domainobjects;
 
+import java.util.List;
+
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
@@ -31,6 +33,7 @@ public class ObjectAndActionInvocation {
     private final ObjectAdapter objectAdapter;
     private final ObjectAction action;
     private final JsonRepresentation arguments;
+    private final List<ObjectAdapter> argAdapters;
     private final ObjectAdapter returnedAdapter;
     private final ActionResultReprRenderer.SelfLink selfLink;
 
@@ -38,11 +41,13 @@ public class ObjectAndActionInvocation {
             final ObjectAdapter objectAdapter,
             final ObjectAction action,
             final JsonRepresentation arguments,
+            final List<ObjectAdapter> argAdapters,
             final ObjectAdapter returnedAdapter,
             final ActionResultReprRenderer.SelfLink selfLink) {
         this.objectAdapter = objectAdapter;
         this.action = action;
         this.arguments = arguments;
+        this.argAdapters = argAdapters;
         this.returnedAdapter = returnedAdapter;
         this.selfLink = selfLink;
     }
@@ -59,6 +64,10 @@ public class ObjectAndActionInvocation {
         return arguments;
     }
 
+    public List<ObjectAdapter> getArgAdapters() {
+        return argAdapters;
+    }
+
     public ObjectAdapter getReturnedAdapter() {
         return returnedAdapter;
     }
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
index 6a81810..90f35c8 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -36,6 +36,7 @@ import org.apache.isis.core.metamodel.adapter.version.Version;
 import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
 import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
@@ -214,7 +215,10 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
 
             if(collectionAdapters != null) {
                 final ObjectSpecification elementSpec = elementSpecFrom(objectAndActionInvocation);
-                final DomainObjectList list = domainObjectListFrom(collectionAdapters, elementSpec);
+                final String actionOwningType = actionOwningTypeFrom(objectAndActionInvocation);
+                final String actionId = actionIdFrom(objectAndActionInvocation);
+                final String actionArguments = actionArgumentsFrom(objectAndActionInvocation);
+                final DomainObjectList list = domainObjectListFrom(collectionAdapters, elementSpec, actionOwningType, actionId, actionArguments);
 
                 adapter = rendererContext.getPersistenceSession().adapterFor(list);
 
@@ -232,13 +236,52 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
         return responseBuilder(responseBuilder);
     }
 
+    private static String actionOwningTypeFrom(final ObjectAndActionInvocation objectAndActionInvocation) {
+        return objectAndActionInvocation.getAction().getOnType().getSpecId().asString();
+    }
+
+    private static String actionIdFrom(final ObjectAndActionInvocation objectAndActionInvocation) {
+        return objectAndActionInvocation.getAction().getId();
+    }
+
+    private static String actionArgumentsFrom(final ObjectAndActionInvocation objectAndActionInvocation) {
+        final StringBuilder buf = new StringBuilder();
+        final List<ObjectActionParameter> parameters = objectAndActionInvocation.getAction().getParameters();
+        final List<ObjectAdapter> argAdapters = objectAndActionInvocation.getArgAdapters();
+        if(parameters.size() == argAdapters.size()) {
+            for (int i = 0; i < parameters.size(); i++) {
+                final ObjectActionParameter param = parameters.get(i);
+                final ObjectAdapter argAdapter = argAdapters.get(i);
+
+                if(buf.length() > 0) {
+                    buf.append(",");
+                }
+                buf.append(param.getName()).append("=");
+                buf.append(abbreviated(titleOf(argAdapter), 8));
+            }
+        }
+
+        return buf.toString();
+    }
+
+    private static String titleOf(final ObjectAdapter argumentAdapter) {
+        return argumentAdapter!=null?argumentAdapter.titleString(null):"";
+    }
+
+    private static String abbreviated(final String str, final int maxLength) {
+        return str.length() < maxLength ? str : str.substring(0, maxLength - 3) + "...";
+    }
+
     private static DomainObjectList domainObjectListFrom(
             final Collection<ObjectAdapter> collectionAdapters,
-            final ObjectSpecification elementSpec) {
+            final ObjectSpecification elementSpec,
+            final String actionOwningType,
+            final String actionId,
+            final String actionArguments) {
 
         final String title = titleFrom(collectionAdapters, elementSpec);
 
-        final DomainObjectList list = new DomainObjectList(title, elementSpec.getSpecId().asString());
+        final DomainObjectList list = new DomainObjectList(title, elementSpec.getSpecId().asString(), actionOwningType, actionId, actionArguments);
         for (final ObjectAdapter adapter : collectionAdapters) {
             list.getObjects().add(adapter.getObject());
         }
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
index da57bcd..40385c4 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
@@ -372,7 +372,7 @@ public class DomainResourceHelper {
                 InteractionInitiatedBy.USER);
 
         final ObjectAndActionInvocation objectAndActionInvocation =
-                new ObjectAndActionInvocation(objectAdapter, action, arguments, returnedAdapter, selfLink);
+                new ObjectAndActionInvocation(objectAdapter, action, arguments, argAdapters, returnedAdapter, selfLink);
 
         // response
         transactionService.flushTransaction();

-- 
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.

[isis] 04/06: ISIS-1882: updates to docs

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch maint-1.16.2
in repository https://gitbox.apache.org/repos/asf/isis.git

commit b0d3b6e154442ecc0afcbc125cfc4ef9245afd58
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Feb 28 11:17:02 2018 +0000

    ISIS-1882: updates to docs
---
 .../_rgfis_presentation-layer_ContentNegotiationService.adoc   | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/adocs/documentation/src/main/asciidoc/guides/rgfis/_rgfis_presentation-layer_ContentNegotiationService.adoc b/adocs/documentation/src/main/asciidoc/guides/rgfis/_rgfis_presentation-layer_ContentNegotiationService.adoc
index 89b6b43..e3d98de 100644
--- a/adocs/documentation/src/main/asciidoc/guides/rgfis/_rgfis_presentation-layer_ContentNegotiationService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgfis/_rgfis_presentation-layer_ContentNegotiationService.adoc
@@ -121,7 +121,15 @@ The other two implementations of `ContentNegotiationService` are:
 
 * `ContentNegotiationServiceForRestfulObjectsV1_0` +
 +
-which returns representations according to the link:http://restfulobjects.org[Restful Objects] spec
+which returns representations according to the link:http://restfulobjects.org[Restful Objects] spec.
++
+One extension (specific to Apache Isis, not part of the RO spec) is that actions can also be invoked with an HTTP `Accept` header of the form:
++
+`application/json;profile=urn:org.restfulobjects:repr-types/object`
++
+If the action result returns a collection then this will automatically converted to a `DomainObjectList` view model.
+This can be useful for generic viewers.
+
 
 * `ContentNegotiationServiceOrgApacheIsisV1` +
 +

-- 
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.

[isis] 01/06: ISIS-1882: adds DomainObjectList, special cases support within JaxbServiceDefault, adds support for new Accept type for action invocation.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch maint-1.16.2
in repository https://gitbox.apache.org/repos/asf/isis.git

commit d6fddaddfa53d7386e67e7dfff47ffadf8cc6959
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Feb 28 08:59:25 2018 +0000

    ISIS-1882: adds DomainObjectList, special cases support within JaxbServiceDefault, adds support for new Accept type for action invocation.
---
 .../applib/services/jaxb/DomainObjectList.java     |  59 ++++++++++
 .../isis/applib/services/jaxb/JaxbService.java     |  54 +++++++--
 .../schema/services/jaxb/JaxbServiceDefault.java   |  19 ++--
 .../jaxbadapters/PersistentEntitiesAdapter.java    |  70 ++++++++++++
 .../services/swagger/internal/Generation.java      |   1 +
 ...entNegotiationServiceForRestfulObjectsV1_0.java | 122 ++++++++++++++++++---
 6 files changed, 294 insertions(+), 31 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/DomainObjectList.java b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/DomainObjectList.java
new file mode 100644
index 0000000..b30ad3c
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/DomainObjectList.java
@@ -0,0 +1,59 @@
+package org.apache.isis.applib.services.jaxb;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.annotation.Collection;
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.schema.utils.jaxbadapters.PersistentEntitiesAdapter;
+
+@XmlRootElement(name = "list")
+@XmlType(
+        propOrder = {
+                "title",
+                "elementType",
+                "objects"
+        }
+)
+@XmlAccessorType(XmlAccessType.FIELD)
+public class DomainObjectList {
+
+    public DomainObjectList() {
+    }
+    public DomainObjectList(final String title, final Class<?> elementType) {
+        this.title = title;
+        this.elementType = elementType.getCanonicalName();
+    }
+
+    private String title;
+    public String title() { return title; }
+
+    private String elementType;
+    @Property(editing = Editing.DISABLED)
+    public String getElementType() {
+        return elementType;
+    }
+
+
+    @XmlJavaTypeAdapter(PersistentEntitiesAdapter.class)
+    private List<Object> objects = Lists.newArrayList();
+
+    @Collection(editing = Editing.DISABLED)
+    public List<Object> getObjects() {
+        return objects;
+    }
+
+    public void setObjects(final List<Object> objects) {
+        this.objects = objects;
+    }
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
index a0d50d5..b028893 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
@@ -109,15 +109,16 @@ public interface JaxbService {
         public Object fromXml(final JAXBContext jaxbContext, final String xml, final Map<String, Object> unmarshallerProperties) {
             try {
 
-                final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+                Object unmarshal = internalFromXml(jaxbContext, xml, unmarshallerProperties);
 
-                for (Map.Entry<String, Object> entry : unmarshallerProperties.entrySet()) {
-                    unmarshaller.setProperty(entry.getKey(), entry.getValue());
-                }
+                if(unmarshal instanceof DomainObjectList) {
 
-                configure(unmarshaller);
+                    // go around the loop again, so can properly deserialize the contents
+                    DomainObjectList domainObjectList = (DomainObjectList) unmarshal;
+                    JAXBContext jaxbContext1 = jaxbContextFor(domainObjectList);
+                    unmarshal = internalFromXml(jaxbContext1, xml, unmarshallerProperties);
+                }
 
-                final Object unmarshal = unmarshaller.unmarshal(new StringReader(xml));
                 return unmarshal;
 
             } catch (final JAXBException ex) {
@@ -125,17 +126,33 @@ public interface JaxbService {
             }
         }
 
+        private Object internalFromXml(
+                final JAXBContext jaxbContext,
+                final String xml,
+                final Map<String, Object> unmarshallerProperties) throws JAXBException {
+            final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+
+            for (Map.Entry<String, Object> entry : unmarshallerProperties.entrySet()) {
+                unmarshaller.setProperty(entry.getKey(), entry.getValue());
+            }
+
+            configure(unmarshaller);
+
+            return unmarshaller.unmarshal(new StringReader(xml));
+        }
+
         @Override
         public <T> T fromXml(final Class<T> domainClass, final String xml) {
             return fromXml(domainClass, xml, Maps.<String,Object>newHashMap());
         }
+
         @Override
         public <T> T fromXml(final Class<T> domainClass, final String xml, final Map<String, Object> unmarshallerProperties) {
             final JAXBContext context = jaxbContextFor(domainClass);
             return (T) fromXml(context, xml, unmarshallerProperties);
         }
 
-        private <T> JAXBContext jaxbContextFor(final Class<T> clazz)  {
+        private static <T> JAXBContext jaxbContextFor(final Class<T> clazz)  {
             try {
                 return JaxbUtil.jaxbContextFor(clazz);
             } catch (RuntimeException e) {
@@ -152,9 +169,9 @@ public interface JaxbService {
         public String toXml(final Object domainObject, final Map<String, Object> marshallerProperties)  {
 
             final Class<?> domainClass = domainObject.getClass();
-            try {
-                final JAXBContext context = jaxbContextFor(domainClass);
+            final JAXBContext context = jaxbContextFor(domainObject);
 
+            try {
                 final Marshaller marshaller = context.createMarshaller();
 
                 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
@@ -205,6 +222,24 @@ public interface JaxbService {
             }
         }
 
+        private static JAXBContext jaxbContextFor(final Object domainObject) {
+            final Class<?> domainClass = domainObject.getClass();
+            final JAXBContext context;
+            if(domainObject instanceof DomainObjectList) {
+                DomainObjectList list = (DomainObjectList) domainObject;
+                final Class<?> elementType;
+                try {
+                    elementType = Thread.currentThread().getContextClassLoader().loadClass(list.getElementType());
+                    context = JAXBContext.newInstance(domainClass, elementType);
+                } catch (JAXBException | ClassNotFoundException e) {
+                    throw new RuntimeException(e);
+                }
+            } else {
+                context = jaxbContextFor(domainClass);
+            }
+            return context;
+        }
+
         /**
          * Optional hook
          */
@@ -233,5 +268,4 @@ public interface JaxbService {
         }
     }
 
-
 }
\ No newline at end of file
diff --git a/core/applib/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java b/core/applib/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java
index a6072b8..0537d10 100644
--- a/core/applib/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java
+++ b/core/applib/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java
@@ -19,10 +19,11 @@ package org.apache.isis.schema.services.jaxb;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
 
-import org.apache.isis.applib.DomainObjectContainer;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.jaxb.JaxbService;
+import org.apache.isis.applib.services.registry.ServiceRegistry;
+import org.apache.isis.schema.utils.jaxbadapters.PersistentEntitiesAdapter;
 import org.apache.isis.schema.utils.jaxbadapters.PersistentEntityAdapter;
 
 @DomainService(
@@ -32,18 +33,20 @@ import org.apache.isis.schema.utils.jaxbadapters.PersistentEntityAdapter;
 public class JaxbServiceDefault extends JaxbService.Simple {
 
     protected void configure(final Unmarshaller unmarshaller) {
-        final PersistentEntityAdapter adapter = new PersistentEntityAdapter();
-        container.injectServicesInto(adapter);
-        unmarshaller.setAdapter(PersistentEntityAdapter.class, adapter);
+        unmarshaller.setAdapter(PersistentEntityAdapter.class,
+                serviceRegistry.injectServicesInto(new PersistentEntityAdapter()));
+        unmarshaller.setAdapter(PersistentEntitiesAdapter.class,
+                serviceRegistry.injectServicesInto(new PersistentEntitiesAdapter()));
     }
 
     protected void configure(final Marshaller marshaller) {
-        final PersistentEntityAdapter adapter = new PersistentEntityAdapter();
-        container.injectServicesInto(adapter);
-        marshaller.setAdapter(PersistentEntityAdapter.class, adapter);
+        marshaller.setAdapter(PersistentEntityAdapter.class,
+                serviceRegistry.injectServicesInto(new PersistentEntityAdapter()));
+        marshaller.setAdapter(PersistentEntitiesAdapter.class,
+                serviceRegistry.injectServicesInto(new PersistentEntitiesAdapter()));
     }
 
     @javax.inject.Inject
-    DomainObjectContainer container;
+    ServiceRegistry serviceRegistry;
 }
 
diff --git a/core/applib/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntitiesAdapter.java b/core/applib/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntitiesAdapter.java
new file mode 100644
index 0000000..a09c56b
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntitiesAdapter.java
@@ -0,0 +1,70 @@
+/**
+ *  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.schema.utils.jaxbadapters;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.bookmark.BookmarkService2;
+import org.apache.isis.schema.common.v1.OidDto;
+import org.apache.isis.schema.common.v1.OidsDto;
+
+public class PersistentEntitiesAdapter extends XmlAdapter<OidsDto, List<Object>> {
+
+    @Override
+    public List<Object> unmarshal(final OidsDto oidsDto) throws Exception {
+
+        List<Object> domainObjects = Lists.newArrayList();
+        for (final OidDto oidDto : oidsDto.getOid()) {
+            final Bookmark bookmark = Bookmark.from(oidDto);
+            Object domainObject = bookmarkService.lookup(bookmark, BookmarkService2.FieldResetPolicy.DONT_RESET);
+            domainObjects.add(domainObject);
+        }
+        return domainObjects;
+    }
+
+    @Override
+    public OidsDto marshal(final List<Object> domainObjects) throws Exception {
+        if(domainObjects == null) {
+            return null;
+        }
+        OidsDto oidsDto = new OidsDto();
+        for (final Object domainObject : domainObjects) {
+            final Bookmark bookmark = getBookmarkService().bookmarkFor(domainObject);
+            oidsDto.getOid().add(bookmark.toOidDto());
+        }
+        return oidsDto;
+    }
+
+    private static String coalesce(final String first, final String second) {
+        return first != null? first: second;
+    }
+
+
+    protected BookmarkService getBookmarkService() {
+        return bookmarkService;
+    }
+
+    @Inject
+    BookmarkService2 bookmarkService;
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/Generation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/Generation.java
index 604624b..caf6d38 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/Generation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/Generation.java
@@ -460,6 +460,7 @@ class Generation {
                         .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/object")
                         .produces("application/json;profile=urn:org.restfulobjects:repr-types/action-result")
                 ;
 
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
index fb666a8..dc124c6 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -18,6 +18,7 @@ package org.apache.isis.viewer.restfulobjects.rendering.service.conneg;
 
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -29,8 +30,12 @@ import javax.ws.rs.core.Response.ResponseBuilder;
 
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.services.jaxb.DomainObjectList;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.version.Version;
+import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
@@ -199,15 +204,74 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
             final RepresentationService.Context2 rendererContext,
             final ObjectAndActionInvocation objectAndActionInvocation) {
 
-        final List<MediaType> list = rendererContext.getAcceptableMediaTypes();
-        ensureCompatibleAcceptHeader(RepresentationType.ACTION_RESULT, list);
+        final ResponseBuilder responseBuilder;
 
-        final ResponseBuilder responseBuilder =
-                buildResponseTo(rendererContext, objectAndActionInvocation, JsonRepresentation.newMap(), null);
+        final List<MediaType> acceptableMediaTypes = rendererContext.getAcceptableMediaTypes();
+        if(isAccepted(RepresentationType.DOMAIN_OBJECT, acceptableMediaTypes, true)) {
+
+            final Collection<ObjectAdapter> collectionAdapters = objectAdaptersFrom(objectAndActionInvocation);
+            final ObjectSpecification elementSpec = elementSpecFrom(objectAndActionInvocation);
+            final DomainObjectList list = domainObjectListFrom(collectionAdapters, elementSpec);
+
+            final ObjectAdapter adapter = rendererContext.getPersistenceSession().adapterFor(list);
+            responseBuilder = buildResponse(rendererContext, adapter);
+
+        } else if(isAccepted(RepresentationType.ACTION_RESULT, acceptableMediaTypes)) {
+            responseBuilder = buildResponseTo(rendererContext, objectAndActionInvocation, JsonRepresentation.newMap(), null);
+        } else {
+            throw RestfulObjectsApplicationException.create(RestfulResponse.HttpStatusCode.NOT_ACCEPTABLE);
+        }
 
         return responseBuilder(responseBuilder);
     }
 
+    private static DomainObjectList domainObjectListFrom(
+            final Collection<ObjectAdapter> collectionAdapters,
+            final ObjectSpecification elementSpec) {
+
+        final String title = titleFrom(collectionAdapters, elementSpec);
+
+        final DomainObjectList list = new DomainObjectList(title, elementSpec.getCorrespondingClass());
+        for (final ObjectAdapter adapter : collectionAdapters) {
+            list.getObjects().add(adapter.getObject());
+        }
+        return list;
+    }
+
+    private static String titleFrom(
+            final Collection<ObjectAdapter> collectionAdapters,
+            final ObjectSpecification elementSpec) {
+        final String singularName = elementSpec.getSingularName();
+        final String pluralName = elementSpec.getPluralName();
+        int size = collectionAdapters.size();
+        final String title;
+        switch (size) {
+        case 0:
+            title = "0 " + pluralName;
+            break;
+        case 1:
+            title = "1 " + singularName;
+            break;
+        default:
+            title = size + " " + pluralName;
+            break;
+        }
+        return title;
+    }
+
+    private ObjectSpecification elementSpecFrom(final ObjectAndActionInvocation objectAndActionInvocation) {
+        final TypeOfFacet typeOfFacet = objectAndActionInvocation.getAction().getFacet(TypeOfFacet.class);
+        return typeOfFacet.valueSpec();
+    }
+
+    private Collection<ObjectAdapter> objectAdaptersFrom(final ObjectAndActionInvocation objectAndActionInvocation) {
+        final ObjectAdapter returnedAdapter = objectAndActionInvocation.getReturnedAdapter();
+        final ObjectSpecification returnType = objectAndActionInvocation.getAction().getReturnType();
+
+        final CollectionFacet collectionFacet = returnType.getFacet(CollectionFacet.class);
+        return collectionFacet.collection(returnedAdapter);
+    }
+
     /**
      * Not API
      */
@@ -248,18 +312,50 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
         // RestEasy will check the basic media types...
         // ... so we just need to check the profile paramter
         final String producedProfile = representationType.getMediaTypeProfile();
-        if(producedProfile != null) {
-            for (MediaType mediaType : acceptableMediaTypes ) {
-                String acceptedProfileValue = mediaType.getParameters().get("profile");
-                if(acceptedProfileValue == null) {
-                    continue;
-                }
-                if(!producedProfile.equals(acceptedProfileValue)) {
-                    throw RestfulObjectsApplicationException.create(RestfulResponse.HttpStatusCode.NOT_ACCEPTABLE);
-                }
+        if (producedProfile == null) {
+            return;
+        }
+        boolean accepted = isAccepted(producedProfile, acceptableMediaTypes);
+        if(!accepted) {
+            throw RestfulObjectsApplicationException.create(RestfulResponse.HttpStatusCode.NOT_ACCEPTABLE);
+        }
+    }
+
+    private boolean isAccepted(
+            final RepresentationType representationType,
+            final List<MediaType> acceptableMediaTypes) {
+        return isAccepted(representationType, acceptableMediaTypes, strictAcceptChecking);
+    }
+
+    private boolean isAccepted(
+            final RepresentationType representationType,
+            final List<MediaType> acceptableMediaTypes,
+            final boolean strictAcceptChecking) {
+        if(!strictAcceptChecking) {
+            return true;
+        }
+        final String producedProfile = representationType.getMediaTypeProfile();
+        if (producedProfile == null) {
+            throw new IllegalArgumentException("RepresentationType " + representationType + " does not specify a 'profile' parameter");
+        }
+        return isAccepted(producedProfile, acceptableMediaTypes);
+    }
+
+    private static boolean isAccepted(
+            final String producedProfile,
+            final List<MediaType> acceptableMediaTypes) {
+        for (MediaType mediaType : acceptableMediaTypes ) {
+            String acceptedProfileValue = mediaType.getParameters().get("profile");
+            if(acceptedProfileValue == null) {
+                continue;
+            }
+            if(!producedProfile.equals(acceptedProfileValue)) {
+                return false;
             }
         }
+        return true;
     }
 
 
+
 }

-- 
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.

[isis] 03/06: ISIS-1882: handles case when action result returns a single adapter, not a collection

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch maint-1.16.2
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 236adc82af50b69244faf976bbd3868d11fe6206
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Feb 28 11:15:11 2018 +0000

    ISIS-1882: handles case when action result returns a single adapter, not a collection
---
 .../ContentNegotiationServiceForRestfulObjectsV1_0.java | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
index 30adc0a..6a81810 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -209,11 +209,18 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
         final List<MediaType> acceptableMediaTypes = rendererContext.getAcceptableMediaTypes();
         if(isAccepted(RepresentationType.DOMAIN_OBJECT, acceptableMediaTypes, true)) {
 
+            final ObjectAdapter adapter;
             final Collection<ObjectAdapter> collectionAdapters = objectAdaptersFrom(objectAndActionInvocation);
-            final ObjectSpecification elementSpec = elementSpecFrom(objectAndActionInvocation);
-            final DomainObjectList list = domainObjectListFrom(collectionAdapters, elementSpec);
 
-            final ObjectAdapter adapter = rendererContext.getPersistenceSession().adapterFor(list);
+            if(collectionAdapters != null) {
+                final ObjectSpecification elementSpec = elementSpecFrom(objectAndActionInvocation);
+                final DomainObjectList list = domainObjectListFrom(collectionAdapters, elementSpec);
+
+                adapter = rendererContext.getPersistenceSession().adapterFor(list);
+
+            } else {
+                adapter = objectAndActionInvocation.getReturnedAdapter();
+            }
             responseBuilder = buildResponse(rendererContext, adapter);
 
         } else if(isAccepted(RepresentationType.ACTION_RESULT, acceptableMediaTypes)) {
@@ -269,7 +276,9 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
         final ObjectSpecification returnType = objectAndActionInvocation.getAction().getReturnType();
 
         final CollectionFacet collectionFacet = returnType.getFacet(CollectionFacet.class);
-        return collectionFacet.collection(returnedAdapter);
+        return collectionFacet != null
+                ? collectionFacet.collection(returnedAdapter)
+                : null;
     }
 
     /**

-- 
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.