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 2013/02/08 19:29:52 UTC

[12/32] ISIS-323: lots more refactoring of RO

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
new file mode 100644
index 0000000..b81d48d
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
@@ -0,0 +1,83 @@
+/**
+ *  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.viewer.restfulobjects.rendering.domainobjects;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
+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.links.Rel;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkFollower;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererException;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererFactoryAbstract;
+
+public class ScalarValueReprRenderer extends ReprRendererAbstract<ScalarValueReprRenderer, ObjectAdapter> {
+
+    private final JsonValueEncoder jsonValueEncoder = new JsonValueEncoder();
+    private ObjectSpecification returnType;
+
+    public static class Factory extends ReprRendererFactoryAbstract {
+        public Factory() {
+            super(RepresentationType.SCALAR_VALUE);
+        }
+
+        @Override
+        public ReprRenderer<?, ?> newRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final JsonRepresentation representation) {
+            return new ScalarValueReprRenderer(resourceContext, linkFollower, getRepresentationType(), representation);
+        }
+    }
+
+    private ScalarValueReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+        super(resourceContext, linkFollower, representationType, representation);
+    }
+
+    @Override
+    public ScalarValueReprRenderer with(final ObjectAdapter objectAdapter) {
+        final EncodableFacet facet = objectAdapter.getSpecification().getFacet(EncodableFacet.class);
+        if (facet == null) {
+            throw ReprRendererException.create("Not an (encodable) value", objectAdapter.titleString());
+        }
+        final Object value = jsonValueEncoder.asObject(objectAdapter);
+
+        representation.mapPut("value", value);
+        return this;
+    }
+
+    @Override
+    public JsonRepresentation render() {
+
+        addLinkToReturnType();
+
+        getExtensions();
+
+        return representation;
+    }
+
+    public ScalarValueReprRenderer withReturnType(final ObjectSpecification returnType) {
+        this.returnType = returnType;
+        return this;
+    }
+
+    private void addLinkToReturnType() {
+        addLink(Rel.RETURN_TYPE, returnType);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java
new file mode 100644
index 0000000..9101ec8
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java
@@ -0,0 +1,107 @@
+/**
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkFollower;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
+
+import com.google.common.base.Strings;
+
+public abstract class AbstractTypeFeatureReprRenderer<R extends ReprRendererAbstract<R, ParentSpecAndFeature<T>>, T extends ObjectFeature> extends ReprRendererAbstract<R, ParentSpecAndFeature<T>> {
+
+    protected ObjectSpecification objectSpecification;
+    protected T objectFeature;
+
+    public AbstractTypeFeatureReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+        super(resourceContext, linkFollower, representationType, representation);
+    }
+
+    public ObjectSpecification getParentSpecification() {
+        return objectSpecification;
+    }
+
+    public T getObjectFeature() {
+        return objectFeature;
+    }
+
+    @Override
+    public R with(final ParentSpecAndFeature<T> specAndFeature) {
+        objectSpecification = specAndFeature.getParentSpec();
+        objectFeature = specAndFeature.getObjectFeature();
+
+        return cast(this);
+    }
+
+    @Override
+    public JsonRepresentation render() {
+
+        addLinkSelfIfRequired();
+        addLinkUpToParent();
+
+        addPropertiesSpecificToFeature();
+
+        addLinksSpecificToFeature();
+        putExtensionsSpecificToFeature();
+
+        return representation;
+    }
+
+    /**
+     * Optional hook method.
+     */
+    protected void addPropertiesSpecificToFeature() {
+    }
+
+    /**
+     * Mandatory hook method.
+     */
+    protected abstract void addLinkSelfIfRequired();
+
+    /**
+     * Mandatory hook method.
+     */
+    protected abstract void addLinkUpToParent();
+
+    /**
+     * Optional hook method.
+     */
+    protected void addLinksSpecificToFeature() {
+    }
+
+    /**
+     * Mandatory hook method.
+     */
+    protected abstract void putExtensionsSpecificToFeature();
+
+    protected void putExtensionsName() {
+        final String friendlyName = getObjectFeature().getName();
+        getExtensions().mapPut("friendlyName", friendlyName);
+    }
+
+    protected void putExtensionsDescriptionIfAvailable() {
+        final String description = getObjectFeature().getDescription();
+        if (!Strings.isNullOrEmpty(description)) {
+            getExtensions().mapPut("description", description);
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java
new file mode 100644
index 0000000..3f4dd53
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeMemberReprRenderer.java
@@ -0,0 +1,75 @@
+/**
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.isis.viewer.restfulobjects.applib.links.Rel;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkFollower;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.MemberType;
+
+public abstract class AbstractTypeMemberReprRenderer<R extends ReprRendererAbstract<R, ParentSpecAndFeature<T>>, T extends ObjectMember> extends AbstractTypeFeatureReprRenderer<R, T> {
+
+    protected MemberType memberType;
+
+    public AbstractTypeMemberReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+        super(resourceContext, linkFollower, representationType, representation);
+    }
+
+    /**
+     * null if the feature is an object action param.
+     * 
+     * @return
+     */
+    public MemberType getMemberType() {
+        return memberType;
+    }
+
+    @Override
+    public R with(final ParentSpecAndFeature<T> specAndFeature) {
+        super.with(specAndFeature);
+        memberType = MemberType.determineFrom(objectFeature);
+
+        // done eagerly so can use as criteria for x-ro-follow-links
+        representation.mapPut(memberType.getJsProp(), objectFeature.getId());
+        representation.mapPut("memberType", memberType.getName());
+
+        return cast(this);
+    }
+
+    @Override
+    protected void addLinkUpToParent() {
+        final LinkBuilder parentLinkBuilder = DomainTypeReprRenderer.newLinkToBuilder(resourceContext, Rel.UP, objectSpecification);
+        getLinks().arrayAdd(parentLinkBuilder.build());
+    }
+
+    @Override
+    protected void addLinkSelfIfRequired() {
+        if (!includesSelf) {
+            return;
+        }
+
+        final ObjectMember objectMember = getObjectFeature();
+        final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.SELF, getRepresentationType(), "domainTypes/%s/%s%s", getParentSpecification().getFullIdentifier(), getMemberType().getUrlPart(), objectMember.getId());
+        getLinks().arrayAdd(linkBuilder.build());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java
new file mode 100644
index 0000000..7f3c08a
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionDescriptionReprRenderer.java
@@ -0,0 +1,102 @@
+/**
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import java.util.List;
+
+import org.apache.isis.core.metamodel.facets.typeof.TypeOfFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+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.links.Rel;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkFollower;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererFactoryAbstract;
+
+public class ActionDescriptionReprRenderer extends AbstractTypeMemberReprRenderer<ActionDescriptionReprRenderer, ObjectAction> {
+
+    public static class Factory extends ReprRendererFactoryAbstract {
+
+        public Factory() {
+            super(RepresentationType.ACTION_DESCRIPTION);
+        }
+
+        @Override
+        public ReprRenderer<?, ?> newRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final JsonRepresentation representation) {
+            return new ActionDescriptionReprRenderer(resourceContext, linkFollower, getRepresentationType(), representation);
+        }
+    }
+
+    public static LinkBuilder newLinkToBuilder(final RendererContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final ObjectAction objectAction) {
+        final String typeFullName = objectSpecification.getFullIdentifier();
+        final String actionId = objectAction.getId();
+        final String url = "domainTypes/" + typeFullName + "/actions/" + actionId;
+        return LinkBuilder.newBuilder(resourceContext, rel, RepresentationType.ACTION_DESCRIPTION, url);
+    }
+
+    public ActionDescriptionReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+        super(resourceContext, linkFollower, representationType, representation);
+    }
+
+    @Override
+    protected void addLinksSpecificToFeature() {
+        addParameters();
+        addLinkToReturnTypeIfAny();
+        addLinkToElementTypeIfAny();
+    }
+
+    private void addParameters() {
+        final JsonRepresentation parameterList = JsonRepresentation.newArray();
+        final List<ObjectActionParameter> parameters = getObjectFeature().getParameters();
+        for (final ObjectActionParameter parameter : parameters) {
+            final LinkBuilder linkBuilder = ActionParameterDescriptionReprRenderer.newLinkToBuilder(getResourceContext(), Rel.ACTION_PARAM, objectSpecification, parameter);
+            parameterList.arrayAdd(linkBuilder.build());
+        }
+
+        representation.mapPut("parameters", parameterList);
+    }
+
+    protected void addLinkToElementTypeIfAny() {
+        final TypeOfFacet facet = getObjectFeature().getFacet(TypeOfFacet.class);
+        if (facet == null) {
+            return;
+        }
+        final ObjectSpecification typeOfSpec = facet.valueSpec();
+        final LinkBuilder linkBuilder = DomainTypeReprRenderer.newLinkToBuilder(getResourceContext(), Rel.ELEMENT_TYPE, typeOfSpec);
+        getLinks().arrayAdd(linkBuilder.build());
+    }
+
+    private void addLinkToReturnTypeIfAny() {
+        final ObjectSpecification returnType = getObjectFeature().getReturnType();
+        if (returnType == null) {
+            return;
+        }
+        final LinkBuilder linkBuilder = DomainTypeReprRenderer.newLinkToBuilder(getResourceContext(), Rel.RETURN_TYPE, returnType);
+        getLinks().arrayAdd(linkBuilder.build());
+    }
+
+    @Override
+    protected void putExtensionsSpecificToFeature() {
+        putExtensionsName();
+        putExtensionsDescriptionIfAvailable();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java
new file mode 100644
index 0000000..fcdf4ca
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ActionParameterDescriptionReprRenderer.java
@@ -0,0 +1,116 @@
+/**
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import org.apache.isis.core.metamodel.facets.maxlen.MaxLengthFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+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.links.Rel;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkFollower;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererFactoryAbstract;
+
+public class ActionParameterDescriptionReprRenderer extends AbstractTypeFeatureReprRenderer<ActionParameterDescriptionReprRenderer, ObjectActionParameter> {
+
+    public static class Factory extends ReprRendererFactoryAbstract {
+
+        public Factory() {
+            super(RepresentationType.ACTION_PARAMETER_DESCRIPTION);
+        }
+
+        @Override
+        public ReprRenderer<?, ?> newRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final JsonRepresentation representation) {
+            return new ActionParameterDescriptionReprRenderer(resourceContext, linkFollower, getRepresentationType(), representation);
+        }
+    }
+
+    public static LinkBuilder newLinkToBuilder(final RendererContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final ObjectActionParameter objectActionParameter) {
+        final String typeFullName = objectSpecification.getFullIdentifier();
+        final ObjectAction objectAction = objectActionParameter.getAction();
+        final String actionId = objectAction.getId();
+        final String paramName = objectActionParameter.getName();
+        final String url = String.format("domainTypes/%s/actions/%s/params/%s", typeFullName, actionId, paramName);
+        return LinkBuilder.newBuilder(resourceContext, rel, RepresentationType.ACTION_PARAMETER_DESCRIPTION, url).withId(deriveId(objectActionParameter));
+    }
+
+    public ActionParameterDescriptionReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+        super(resourceContext, linkFollower, representationType, representation);
+    }
+
+    @Override
+    public ActionParameterDescriptionReprRenderer with(final ParentSpecAndFeature<ObjectActionParameter> specAndFeature) {
+        super.with(specAndFeature);
+
+        // done eagerly so can use as criteria for x-ro-follow-links
+        representation.mapPut("id", deriveId());
+
+        return this;
+    }
+
+    protected String deriveId() {
+        return deriveId(getObjectFeature());
+    }
+
+    private static String deriveId(final ObjectActionParameter objectActionParameter) {
+        return objectActionParameter.getAction().getId() + "-" + objectActionParameter.getName();
+    }
+
+    @Override
+    protected void addLinkSelfIfRequired() {
+        if (!includesSelf) {
+            return;
+        }
+        getLinks().arrayAdd(newLinkToBuilder(getResourceContext(), Rel.SELF, getParentSpecification(), getObjectFeature()).build());
+    }
+
+    @Override
+    protected void addLinkUpToParent() {
+        final ObjectAction parentAction = this.objectFeature.getAction();
+
+        final LinkBuilder parentLinkBuilder = ActionDescriptionReprRenderer.newLinkToBuilder(resourceContext, Rel.UP, objectSpecification, parentAction);
+        getLinks().arrayAdd(parentLinkBuilder.build());
+    }
+
+    @Override
+    protected void addPropertiesSpecificToFeature() {
+        representation.mapPut("name", getObjectFeature().getName());
+        representation.mapPut("number", getObjectFeature().getNumber());
+        representation.mapPut("optional", getObjectFeature().isOptional());
+        final MaxLengthFacet maxLength = getObjectFeature().getFacet(MaxLengthFacet.class);
+        if (maxLength != null && !maxLength.isNoop()) {
+            representation.mapPut("maxLength", maxLength.value());
+        }
+    }
+
+    @Override
+    protected void addLinksSpecificToFeature() {
+        final LinkBuilder linkBuilder = DomainTypeReprRenderer.newLinkToBuilder(resourceContext, Rel.RETURN_TYPE, objectFeature.getSpecification());
+        getLinks().arrayAdd(linkBuilder.build());
+    }
+
+    @Override
+    protected void putExtensionsSpecificToFeature() {
+        putExtensionsName();
+        putExtensionsDescriptionIfAvailable();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java
new file mode 100644
index 0000000..0f008b9
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/CollectionDescriptionReprRenderer.java
@@ -0,0 +1,75 @@
+/**
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.isis.viewer.restfulobjects.applib.links.Rel;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkFollower;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererFactoryAbstract;
+
+public class CollectionDescriptionReprRenderer extends AbstractTypeMemberReprRenderer<CollectionDescriptionReprRenderer, OneToManyAssociation> {
+
+    public static class Factory extends ReprRendererFactoryAbstract {
+
+        public Factory() {
+            super(RepresentationType.COLLECTION_DESCRIPTION);
+        }
+
+        @Override
+        public ReprRenderer<?, ?> newRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final JsonRepresentation representation) {
+            return new CollectionDescriptionReprRenderer(resourceContext, linkFollower, getRepresentationType(), representation);
+        }
+    }
+
+    public static LinkBuilder newLinkToBuilder(final RendererContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final OneToManyAssociation collection) {
+        final String typeFullName = objectSpecification.getFullIdentifier();
+        final String collectionId = collection.getId();
+        final String url = "domainTypes/" + typeFullName + "/collections/" + collectionId;
+        return LinkBuilder.newBuilder(resourceContext, rel, RepresentationType.COLLECTION_DESCRIPTION, url);
+    }
+
+    public CollectionDescriptionReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+        super(resourceContext, linkFollower, representationType, representation);
+    }
+
+    @Override
+    protected void addLinksSpecificToFeature() {
+        addLinkToElementTypeIfAny();
+    }
+
+    private void addLinkToElementTypeIfAny() {
+        final ObjectSpecification elementType = getObjectFeature().getSpecification();
+        if (elementType == null) {
+            return;
+        }
+        final LinkBuilder linkBuilder = DomainTypeReprRenderer.newLinkToBuilder(getResourceContext(), Rel.ELEMENT_TYPE, elementType);
+        getLinks().arrayAdd(linkBuilder.build());
+    }
+
+    @Override
+    protected void putExtensionsSpecificToFeature() {
+        putExtensionsName();
+        putExtensionsDescriptionIfAvailable();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
new file mode 100644
index 0000000..2b2df40
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
@@ -0,0 +1,190 @@
+/**
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import java.util.List;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionContainer.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.isis.viewer.restfulobjects.applib.links.Rel;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkFollower;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererFactoryAbstract;
+import org.codehaus.jackson.node.NullNode;
+
+import com.google.common.base.Strings;
+
+public class DomainTypeReprRenderer extends ReprRendererAbstract<DomainTypeReprRenderer, ObjectSpecification> {
+
+    public static class Factory extends ReprRendererFactoryAbstract {
+        public Factory() {
+            super(RepresentationType.DOMAIN_TYPE);
+        }
+
+        @Override
+        public ReprRenderer<?, ?> newRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final JsonRepresentation representation) {
+            return new DomainTypeReprRenderer(resourceContext, linkFollower, getRepresentationType(), representation);
+        }
+    }
+
+    public static LinkBuilder newLinkToBuilder(final RendererContext resourceContext, final Rel rel, final ObjectSpecification objectSpec) {
+        final String typeFullName = objectSpec.getFullIdentifier();
+        final String url = "domainTypes/" + typeFullName;
+        return LinkBuilder.newBuilder(resourceContext, rel, RepresentationType.DOMAIN_TYPE, url);
+    }
+
+    private ObjectSpecification objectSpecification;
+
+    public DomainTypeReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+        super(resourceContext, linkFollower, representationType, representation);
+    }
+
+    @Override
+    public DomainTypeReprRenderer with(final ObjectSpecification objectSpecification) {
+        this.objectSpecification = objectSpecification;
+        return cast(this);
+    }
+
+    @Override
+    public JsonRepresentation render() {
+
+        if (objectSpecification == null) {
+            throw new IllegalStateException("ObjectSpecification not specified");
+        }
+
+        // self
+        if (includesSelf) {
+            final JsonRepresentation selfLink = newLinkToBuilder(getResourceContext(), Rel.SELF, objectSpecification).build();
+            getLinks().arrayAdd(selfLink);
+        }
+
+        representation.mapPut("canonicalName", objectSpecification.getFullIdentifier());
+        addMembers();
+
+        addTypeActions();
+
+        putExtensionsNames();
+        putExtensionsDescriptionIfAvailable();
+        putExtensionsIfService();
+
+        return representation;
+    }
+
+    private void addMembers() {
+        final JsonRepresentation membersList = JsonRepresentation.newArray();
+        representation.mapPut("members", membersList);
+        final List<ObjectAssociation> associations = objectSpecification.getAssociations();
+        for (final ObjectAssociation association : associations) {
+            if (association.isOneToOneAssociation()) {
+                final OneToOneAssociation property = (OneToOneAssociation) association;
+                final LinkBuilder linkBuilder = PropertyDescriptionReprRenderer.newLinkToBuilder(getResourceContext(), Rel.PROPERTY, objectSpecification, property);
+                membersList.arrayAdd(linkBuilder.build());
+            } else if (association.isOneToManyAssociation()) {
+                final OneToManyAssociation collection = (OneToManyAssociation) association;
+                final LinkBuilder linkBuilder = CollectionDescriptionReprRenderer.newLinkToBuilder(getResourceContext(), Rel.PROPERTY, objectSpecification, collection);
+                membersList.arrayAdd(linkBuilder.build());
+            }
+        }
+        final List<ObjectAction> actions = objectSpecification.getObjectActions(Contributed.INCLUDED);
+        for (final ObjectAction action : actions) {
+            final LinkBuilder linkBuilder = ActionDescriptionReprRenderer.newLinkToBuilder(getResourceContext(), Rel.ACTION, objectSpecification, action);
+            membersList.arrayAdd(linkBuilder.build());
+        }
+    }
+
+    private JsonRepresentation getTypeActions() {
+        JsonRepresentation typeActions = representation.getArray("typeActions");
+        if (typeActions == null) {
+            typeActions = JsonRepresentation.newArray();
+            representation.mapPut("typeActions", typeActions);
+        }
+        return typeActions;
+    }
+
+    private void addTypeActions() {
+        getTypeActions().arrayAdd(linkToIsSubtypeOf());
+        getTypeActions().arrayAdd(linkToIsSupertypeOf());
+        getTypeActions().arrayAdd(linkToNewTransientInstance());
+    }
+
+    private JsonRepresentation linkToIsSubtypeOf() {
+        final String url = "domainTypes/" + objectSpecification.getFullIdentifier() + "/typeactions/isSubtypeOf/invoke";
+
+        final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.TYPE_ACTION, RepresentationType.TYPE_ACTION_RESULT, url);
+        final JsonRepresentation arguments = argumentsTo(getResourceContext(), "supertype", null);
+        final JsonRepresentation link = linkBuilder.withArguments(arguments).withId("isSubtypeOf").build();
+        return link;
+    }
+
+    private JsonRepresentation linkToIsSupertypeOf() {
+        final String url = "domainTypes/" + objectSpecification.getFullIdentifier() + "/typeactions/isSupertypeOf/invoke";
+
+        final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.TYPE_ACTION, RepresentationType.TYPE_ACTION_RESULT, url);
+        final JsonRepresentation arguments = argumentsTo(getResourceContext(), "subtype", null);
+        final JsonRepresentation link = linkBuilder.withArguments(arguments).withId("isSupertypeOf").build();
+        return link;
+    }
+
+    private JsonRepresentation linkToNewTransientInstance() {
+        final String url = "domainTypes/" + objectSpecification.getFullIdentifier() + "/typeactions/newTransientInstance/invoke";
+
+        final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.TYPE_ACTION, RepresentationType.TYPE_ACTION_RESULT, url);
+        final JsonRepresentation link = linkBuilder.withId("newTransientInstance").build();
+        return link;
+    }
+
+    public static JsonRepresentation argumentsTo(final RendererContext resourceContext, final String paramName, final ObjectSpecification objectSpec) {
+        final JsonRepresentation arguments = JsonRepresentation.newMap();
+        final JsonRepresentation link = JsonRepresentation.newMap();
+        arguments.mapPut(paramName, link);
+        if (objectSpec != null) {
+            link.mapPut("href", resourceContext.urlFor("domainTypes/" + objectSpec.getFullIdentifier()));
+        } else {
+            link.mapPut("href", NullNode.instance);
+        }
+        return arguments;
+    }
+
+    protected void putExtensionsNames() {
+        final String singularName = objectSpecification.getSingularName();
+        getExtensions().mapPut("friendlyName", singularName);
+
+        final String pluralName = objectSpecification.getPluralName();
+        getExtensions().mapPut("pluralName", pluralName);
+    }
+
+    protected void putExtensionsDescriptionIfAvailable() {
+        final String description = objectSpecification.getDescription();
+        if (!Strings.isNullOrEmpty(description)) {
+            getExtensions().mapPut("description", description);
+        }
+    }
+
+    protected void putExtensionsIfService() {
+        getExtensions().mapPut("isService", objectSpecification.isService());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ObjectSpecAndSuperSpec.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ObjectSpecAndSuperSpec.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ObjectSpecAndSuperSpec.java
new file mode 100644
index 0000000..98b989e
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ObjectSpecAndSuperSpec.java
@@ -0,0 +1,41 @@
+/*
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+public class ObjectSpecAndSuperSpec {
+
+    private final ObjectSpecification objectSpecification;
+    private final ObjectSpecification superSpecification;
+
+    public ObjectSpecAndSuperSpec(final ObjectSpecification objectSpecification, final ObjectSpecification superSpecification) {
+        this.objectSpecification = objectSpecification;
+        this.superSpecification = superSpecification;
+    }
+
+    public ObjectSpecification getObjectSpecification() {
+        return objectSpecification;
+    }
+
+    public ObjectSpecification getSuperSpecification() {
+        return superSpecification;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndAction.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndAction.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndAction.java
new file mode 100644
index 0000000..5892ade
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndAction.java
@@ -0,0 +1,30 @@
+/*
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+
+public class ParentSpecAndAction extends ParentSpecAndFeature<ObjectAction> {
+
+    public ParentSpecAndAction(final ObjectSpecification objectSpecification, final ObjectAction action) {
+        super(objectSpecification, action);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndActionParam.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndActionParam.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndActionParam.java
new file mode 100644
index 0000000..b2e180e
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndActionParam.java
@@ -0,0 +1,30 @@
+/*
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+
+public class ParentSpecAndActionParam extends ParentSpecAndFeature<ObjectActionParameter> {
+
+    public ParentSpecAndActionParam(final ObjectSpecification objectSpecification, final ObjectActionParameter actionParam) {
+        super(objectSpecification, actionParam);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndCollection.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndCollection.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndCollection.java
new file mode 100644
index 0000000..d2c6029
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndCollection.java
@@ -0,0 +1,30 @@
+/*
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+public class ParentSpecAndCollection extends ParentSpecAndFeature<OneToManyAssociation> {
+
+    public ParentSpecAndCollection(final ObjectSpecification objectSpecification, final OneToManyAssociation collection) {
+        super(objectSpecification, collection);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndFeature.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndFeature.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndFeature.java
new file mode 100644
index 0000000..d1ed13f
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndFeature.java
@@ -0,0 +1,42 @@
+/*
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
+
+public abstract class ParentSpecAndFeature<T extends ObjectFeature> {
+
+    private final ObjectSpecification parentSpec;
+    private final T objectFeature;
+
+    public ParentSpecAndFeature(final ObjectSpecification objectSpecification, final T objectFeature) {
+        this.parentSpec = objectSpecification;
+        this.objectFeature = objectFeature;
+    }
+
+    public ObjectSpecification getParentSpec() {
+        return parentSpec;
+    }
+
+    public T getObjectFeature() {
+        return objectFeature;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndProperty.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndProperty.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndProperty.java
new file mode 100644
index 0000000..0ec418d
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/ParentSpecAndProperty.java
@@ -0,0 +1,30 @@
+/*
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+
+public class ParentSpecAndProperty extends ParentSpecAndFeature<OneToOneAssociation> {
+
+    public ParentSpecAndProperty(final ObjectSpecification objectSpecification, final OneToOneAssociation property) {
+        super(objectSpecification, property);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java
new file mode 100644
index 0000000..b11d3fc
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/PropertyDescriptionReprRenderer.java
@@ -0,0 +1,85 @@
+/**
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import org.apache.isis.core.metamodel.facets.maxlen.MaxLengthFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.isis.viewer.restfulobjects.applib.links.Rel;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkFollower;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererFactoryAbstract;
+
+public class PropertyDescriptionReprRenderer extends AbstractTypeMemberReprRenderer<PropertyDescriptionReprRenderer, OneToOneAssociation> {
+
+    public static class Factory extends ReprRendererFactoryAbstract {
+
+        public Factory() {
+            super(RepresentationType.PROPERTY_DESCRIPTION);
+        }
+
+        @Override
+        public ReprRenderer<?, ?> newRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final JsonRepresentation representation) {
+            return new PropertyDescriptionReprRenderer(resourceContext, linkFollower, getRepresentationType(), representation);
+        }
+    }
+
+    public static LinkBuilder newLinkToBuilder(final RendererContext resourceContext, final Rel rel, final ObjectSpecification objectSpecification, final OneToOneAssociation property) {
+        final String typeFullName = objectSpecification.getFullIdentifier();
+        final String propertyId = property.getId();
+        final String url = "domainTypes/" + typeFullName + "/properties/" + propertyId;
+        return LinkBuilder.newBuilder(resourceContext, rel, RepresentationType.PROPERTY_DESCRIPTION, url);
+    }
+
+    public PropertyDescriptionReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+        super(resourceContext, linkFollower, representationType, representation);
+    }
+
+    @Override
+    protected void addLinksSpecificToFeature() {
+        addLinkToReturnTypeIfAny();
+    }
+
+    @Override
+    protected void addPropertiesSpecificToFeature() {
+        representation.mapPut("optional", !getObjectFeature().isMandatory());
+        final MaxLengthFacet maxLength = getObjectFeature().getFacet(MaxLengthFacet.class);
+        if (maxLength != null && !maxLength.isNoop()) {
+            representation.mapPut("maxLength", maxLength.value());
+        }
+    }
+
+    private void addLinkToReturnTypeIfAny() {
+        final ObjectSpecification returnType = getObjectFeature().getSpecification();
+        if (returnType == null) {
+            return;
+        }
+        final LinkBuilder linkBuilder = DomainTypeReprRenderer.newLinkToBuilder(getResourceContext(), Rel.RETURN_TYPE, returnType);
+        getLinks().arrayAdd(linkBuilder.build());
+    }
+
+    @Override
+    protected void putExtensionsSpecificToFeature() {
+        putExtensionsName();
+        putExtensionsDescriptionIfAvailable();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeActionResultReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeActionResultReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeActionResultReprRenderer.java
new file mode 100644
index 0000000..83a258d
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeActionResultReprRenderer.java
@@ -0,0 +1,79 @@
+/**
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+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.links.LinkRepresentation;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkFollower;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererFactoryAbstract;
+
+public class TypeActionResultReprRenderer extends ReprRendererAbstract<TypeActionResultReprRenderer, ObjectSpecification> {
+
+    public static class Factory extends ReprRendererFactoryAbstract {
+        public Factory() {
+            super(RepresentationType.TYPE_ACTION_RESULT);
+        }
+
+        @Override
+        public ReprRenderer<?, ?> newRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final JsonRepresentation representation) {
+            return new TypeActionResultReprRenderer(resourceContext, linkFollower, getRepresentationType(), representation);
+        }
+    }
+
+    private ObjectSpecification objectSpecification;
+    private LinkRepresentation selfLink;
+    private Object value;
+
+    public TypeActionResultReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+        super(resourceContext, linkFollower, representationType, representation);
+    }
+
+    @Override
+    public TypeActionResultReprRenderer with(final ObjectSpecification objectSpecification) {
+        this.objectSpecification = objectSpecification;
+        return cast(this);
+    }
+
+    public TypeActionResultReprRenderer withValue(final Object value) {
+        this.value = value;
+        return this;
+    }
+
+    @Override
+    public JsonRepresentation render() {
+        if (includesSelf && selfLink != null) {
+            getLinks().arrayAdd(selfLink);
+        }
+
+        if (value != null) {
+            representation.mapPut("value", value);
+        }
+        getExtensions();
+
+        return representation;
+    }
+
+    protected void putExtensionsIfService() {
+        getExtensions().mapPut("isService", objectSpecification.isService());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java
new file mode 100644
index 0000000..5536306
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/TypeListReprRenderer.java
@@ -0,0 +1,80 @@
+/*
+ *  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.viewer.restfulobjects.rendering.domaintypes;
+
+import java.util.Collection;
+
+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.links.Rel;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
+import org.apache.isis.viewer.restfulobjects.rendering.LinkFollower;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererFactoryAbstract;
+
+public class TypeListReprRenderer extends ReprRendererAbstract<TypeListReprRenderer, Collection<ObjectSpecification>> {
+
+    private Collection<ObjectSpecification> specifications;
+
+    public static class Factory extends ReprRendererFactoryAbstract {
+        public Factory() {
+            super(RepresentationType.TYPE_LIST);
+        }
+
+        @Override
+        public ReprRenderer<?, ?> newRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final JsonRepresentation representation) {
+            return new TypeListReprRenderer(resourceContext, linkFollower, getRepresentationType(), representation);
+        }
+    }
+
+    private TypeListReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+        super(resourceContext, linkFollower, representationType, representation);
+    }
+
+    @Override
+    public TypeListReprRenderer with(final Collection<ObjectSpecification> specifications) {
+        this.specifications = specifications;
+        return this;
+    }
+
+    @Override
+    public JsonRepresentation render() {
+
+        // self
+        if (includesSelf) {
+            withSelf("domainTypes");
+        }
+
+        final JsonRepresentation specList = JsonRepresentation.newArray();
+        for (final ObjectSpecification objectSpec : specifications) {
+            final LinkBuilder linkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.DOMAIN_TYPE, RepresentationType.DOMAIN_TYPE, "domainTypes/%s", objectSpec.getFullIdentifier());
+            specList.arrayAdd(linkBuilder.build());
+        }
+
+        representation.mapPut("values", specList);
+
+        getExtensions(); // empty
+
+        return representation;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/GraphUtil.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/GraphUtil.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/GraphUtil.java
new file mode 100644
index 0000000..c797b1f
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/GraphUtil.java
@@ -0,0 +1,60 @@
+/*
+ *  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.viewer.restfulobjects.rendering.util;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.viewer.restfulobjects.applib.util.PathNode;
+
+import com.google.common.collect.Maps;
+
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public final class GraphUtil {
+
+    private GraphUtil() {
+    }
+
+    public final static Map<PathNode, Map> asGraph(final List<List<String>> links) {
+        if (links == null) {
+            return Collections.emptyMap();
+        }
+        final Map<PathNode, Map> map = Maps.newHashMap();
+        for (final List<String> link : links) {
+            GraphUtil.mergeInto(link, map);
+        }
+        return map;
+    }
+
+    private static void mergeInto(final List<String> list, final Map<PathNode, Map> map) {
+        if (list.size() == 0) {
+            return;
+        }
+        final String str = list.get(0);
+        final PathNode node = PathNode.parse(str);
+        Map<PathNode, Map> submap = map.get(node);
+        if (submap == null) {
+            submap = Maps.newHashMap();
+            map.put(node, submap);
+        }
+        mergeInto(list.subList(1, list.size()), submap);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/InputStreamUtil.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/InputStreamUtil.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/InputStreamUtil.java
new file mode 100644
index 0000000..44d7697
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/InputStreamUtil.java
@@ -0,0 +1,64 @@
+/*
+ *  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.viewer.restfulobjects.rendering.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+public final class InputStreamUtil {
+
+    private InputStreamUtil() {
+    }
+
+    public static List<String> getArgs(final InputStream body) {
+        // will be sorted by arg
+        final Map<String, String> args = new TreeMap<String, String>();
+        if (body == null) {
+            return listOfValues(args);
+        }
+        try {
+            final InputStreamReader inputStreamReader = new InputStreamReader(body);
+            final BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+            String readLine = bufferedReader.readLine();
+            while (readLine != null) {
+                final String[] keyValuePairs = readLine.split("&");
+                for (final String keyValuePair : keyValuePairs) {
+                    final String[] keyThenValue = keyValuePair.split("=");
+                    args.put(keyThenValue[0], keyThenValue[1]);
+                }
+                readLine = bufferedReader.readLine();
+            }
+            return listOfValues(args);
+        } catch (final IOException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private static ArrayList<String> listOfValues(final Map<String, String> args) {
+        // returns the values in the order of the keys
+        return new ArrayList<String>(args.values());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/ListUtils.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/ListUtils.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/ListUtils.java
new file mode 100644
index 0000000..e2470eb
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/ListUtils.java
@@ -0,0 +1,38 @@
+/*
+ *  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.viewer.restfulobjects.rendering.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class ListUtils {
+
+    private ListUtils() {
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> List<T> toList(final Object[] objects) {
+        final List<T> list = new ArrayList<T>();
+        for (final Object o : objects) {
+            list.add((T) o);
+        }
+        return list;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/MapUtils.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/MapUtils.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/MapUtils.java
new file mode 100644
index 0000000..915d504
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/MapUtils.java
@@ -0,0 +1,48 @@
+/*
+ *  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.viewer.restfulobjects.rendering.util;
+
+import java.util.Collections;
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+
+public final class MapUtils {
+
+    /**
+     * Returns an immutable map based on a list of key/value pairs.
+     */
+    public static Map<String, String> mapOf(final String... keyOrValues) {
+        if (keyOrValues.length % 2 != 0) {
+            throw new IllegalArgumentException("Must provide an even number of arguments");
+        }
+        final Map<String, String> map = Maps.newLinkedHashMap();
+        String key = null;
+        for (final String keyOrValue : keyOrValues) {
+            if (key != null) {
+                map.put(key, keyOrValue);
+                key = null;
+            } else {
+                key = keyOrValue;
+            }
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/NOTUSED_ActionUtils.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/NOTUSED_ActionUtils.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/NOTUSED_ActionUtils.java
new file mode 100644
index 0000000..f9d8242
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/NOTUSED_ActionUtils.java
@@ -0,0 +1,53 @@
+/*
+ *  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.viewer.restfulobjects.rendering.util;
+
+import java.util.List;
+
+import org.apache.isis.core.metamodel.spec.ActionType;
+import org.apache.isis.core.metamodel.spec.ObjectActionSet;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+
+import com.google.common.collect.Lists;
+
+// TODO: unused, apparently, to remove
+final class NOTUSED_ActionUtils {
+
+    private NOTUSED_ActionUtils() {
+    }
+
+    
+    @SuppressWarnings("unused")
+    private static List<ObjectAction> flattened(final List<ObjectAction> objectActions) {
+        final List<ObjectAction> actions = Lists.newArrayList();
+        for (final ObjectAction action : objectActions) {
+            if (action.getType() == ActionType.SET) {
+                final ObjectActionSet actionSet = (ObjectActionSet) action;
+                final List<ObjectAction> subActions = actionSet.getActions();
+                for (final ObjectAction subAction : subActions) {
+                    actions.add(subAction);
+                }
+            } else {
+                actions.add(action);
+            }
+        }
+        return actions;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/OidUtils.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/OidUtils.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/OidUtils.java
new file mode 100644
index 0000000..7f1b070
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/OidUtils.java
@@ -0,0 +1,52 @@
+/*
+ *  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.viewer.restfulobjects.rendering.util;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOidDefault;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+
+public final class OidUtils {
+
+    private OidUtils() {
+    }
+
+    public static ObjectAdapter getObjectAdapter(final RendererContext resourceContext, final String oidEncodedStr) {
+        final String oidStr = UrlDecoderUtils.urlDecode(oidEncodedStr);
+        final RootOid rootOid = RootOidDefault.deStringEncoded(oidStr, getOidMarshaller());
+        return resourceContext.getAdapterManager().adapterFor(rootOid);
+    }
+
+    public static String getOidStr(final RendererContext resourceContext, final ObjectAdapter objectAdapter) {
+        final Oid oid = objectAdapter.getOid();
+        if(!(oid instanceof RootOid)) {
+            throw new IllegalArgumentException("objectAdapter must be a root adapter");
+        }
+        return oid != null ? oid.enString(getOidMarshaller()) : null;
+    }
+
+    protected static OidMarshaller getOidMarshaller() {
+		return new OidMarshaller();
+	}
+
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/StringUtil.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/StringUtil.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/StringUtil.java
new file mode 100644
index 0000000..761a18d
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/StringUtil.java
@@ -0,0 +1,38 @@
+/*
+ *  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.viewer.restfulobjects.rendering.util;
+
+public final class StringUtil {
+
+    private StringUtil() {
+    }
+
+    public static String concat(final String... lines) {
+        final StringBuilder buf = new StringBuilder();
+        for (final String line : lines) {
+            buf.append(line);
+        }
+        return buf.toString();
+    }
+
+    public static String quote(final String val) {
+        return "\"" + val + "\"";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/UrlDecoderUtils.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/UrlDecoderUtils.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/UrlDecoderUtils.java
new file mode 100644
index 0000000..ef11e5c
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/UrlDecoderUtils.java
@@ -0,0 +1,41 @@
+/*
+ *  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.viewer.restfulobjects.rendering.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+import javax.ws.rs.WebApplicationException;
+
+public final class UrlDecoderUtils {
+
+    private UrlDecoderUtils() {
+    }
+
+    public static final String URL_ENCODING_CHAR_SET = "UTF-8";
+    
+    public static String urlDecode(final String oidStr) {
+        try {
+            return URLDecoder.decode(oidStr, URL_ENCODING_CHAR_SET);
+        } catch (final UnsupportedEncodingException e) {
+            throw new WebApplicationException(e);
+        }
+    }
+
+}