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 2011/10/25 09:10:23 UTC

svn commit: r1188543 - in /incubator/isis/trunk/framework: core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ core/metamodel/src/test/java/org/apach...

Author: danhaywood
Date: Tue Oct 25 07:10:22 2011
New Revision: 1188543

URL: http://svn.apache.org/viewvc?rev=1188543&view=rev
Log:
ISIS-109: added most of the formal domain model representations (chapters 20~24 of v0.48 of the RO spec)

Added:
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/AbstractTypeMemberReprBuilder.java
Modified:
    incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
    incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
    incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
    incubator/isis/trunk/framework/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstractTest_getName.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/Rel.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/AbstractTypeFeatureReprBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeReprRenderer.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeResourceServerside.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeActionParamReprRenderer.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeActionReprRenderer.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeCollectionReprRenderer.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypePropertyReprRenderer.java

Modified: incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java (original)
+++ incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java Tue Oct 25 07:10:22 2011
@@ -73,7 +73,8 @@ public interface ObjectActionParameter e
      * a name from this, eg "First Name" becomes "firstName".
      * <li>Otherwise we use the type, eg "string".
      * <li>If there is more than one parameter
-     * of the same type, then we use a numeric suffix (eg "string1", "string2").
+     * of the same type, then we use a numeric suffix (eg "string1", "string2").  Wrappers
+     * and primitives are considered to be the same type.
      * </ul>
      */
     String getName();

Modified: incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java (original)
+++ incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java Tue Oct 25 07:10:22 2011
@@ -116,14 +116,18 @@ public abstract class ObjectActionParame
 
             @Override
             public boolean accept(ObjectActionParameter t) {
-                return t.getSpecification() == getSpecification();
+                return equalsShortIdentifier(t.getSpecification(), getSpecification());
+            }
+
+            protected boolean equalsShortIdentifier(final ObjectSpecification spec1, final ObjectSpecification spec2) {
+                return spec1.getShortIdentifier().toLowerCase().equals(spec2.getShortIdentifier().toLowerCase());
             }
         });
         if (parameters.size() == 1) {
             return StringUtils.camelLowerFirst(name);
         }
         int indexOf = parameters.indexOf(this);
-        return StringUtils.camel(name + indexOf);
+        return StringUtils.camelLowerFirst(name + (indexOf+1));
     }
 
     @Override

Modified: incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java (original)
+++ incubator/isis/trunk/framework/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java Tue Oct 25 07:10:22 2011
@@ -174,8 +174,7 @@ public abstract class ObjectMemberAbstra
     public String getName() {
         final NamedFacet facet = getFacet(NamedFacet.class);
         String name = facet.value();
-        name = name == null ? defaultName : name;
-        return name;
+        return name != null ? name : defaultName;
     }
 
     @Override

Modified: incubator/isis/trunk/framework/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstractTest_getName.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstractTest_getName.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstractTest_getName.java (original)
+++ incubator/isis/trunk/framework/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstractTest_getName.java Tue Oct 25 07:10:22 2011
@@ -22,8 +22,14 @@ package org.apache.isis.core.metamodel.s
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 
-import com.google.common.collect.Lists;
-
+import org.apache.isis.applib.filter.Filter;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.TypedHolder;
+import org.apache.isis.core.metamodel.facets.named.NamedFacet;
+import org.apache.isis.core.metamodel.spec.Instance;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
@@ -33,14 +39,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.apache.isis.applib.filter.Filter;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.facets.TypedHolder;
-import org.apache.isis.core.metamodel.facets.named.NamedFacet;
-import org.apache.isis.core.metamodel.spec.Instance;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import com.google.common.collect.Lists;
 
 @RunWith(JMock.class)
 public class ObjectActionParameterAbstractTest_getName {
@@ -185,7 +184,8 @@ public class ObjectActionParameterAbstra
             }
         });
 
-        assertThat(objectActionParameter.getName(), is("string1"));
+        assertThat(objectActionParameter.getName(), is("string2"));
     }
 
+
 }

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/Rel.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/Rel.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/Rel.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/Rel.java Tue Oct 25 07:10:22 2011
@@ -43,9 +43,9 @@ public enum Rel {
     PROPERTY("property"), 
     COLLECTION("collection"), 
     ACTION("action"), 
-    ACTIONPARAM("actionparam"), 
-    RETURNTYPE("returntype"), 
-    ELEMENTTYPE("elementtype"), 
+    ACTION_PARAM("actionparam"), 
+    RETURN_TYPE("returntype"), 
+    ELEMENT_TYPE("elementtype"), 
     CAPABILITIES("capabilities"), 
     USER("user"),
     SERVICES("services"), 

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/AbstractTypeFeatureReprBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/AbstractTypeFeatureReprBuilder.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/AbstractTypeFeatureReprBuilder.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/AbstractTypeFeatureReprBuilder.java Tue Oct 25 07:10:22 2011
@@ -28,12 +28,15 @@ import org.apache.isis.viewer.json.viewe
 import org.apache.isis.viewer.json.viewer.representations.ReprRendererAbstract;
 import org.apache.isis.viewer.json.viewer.resources.domainobjects.MemberType;
 
+import com.google.common.base.Strings;
+
 public abstract class AbstractTypeFeatureReprBuilder<R extends ReprRendererAbstract<R, SpecAndFeature<T>>, T extends ObjectFeature> extends ReprRendererAbstract<R, SpecAndFeature<T>> {
 
     protected ObjectSpecification objectSpecification;
-    protected MemberType memberType;
     protected T objectFeature;
 
+    protected ObjectSpecification parentSpec;
+
     public AbstractTypeFeatureReprBuilder(ResourceContext resourceContext, LinkFollower linkFollower, RepresentationType representationType, JsonRepresentation representation) {
         super(resourceContext, linkFollower, representationType, representation);
     }
@@ -46,56 +49,64 @@ public abstract class AbstractTypeFeatur
         return objectFeature;
     }
 
-    /**
-     * null if the feature is an object action param.
-     * @return
-     */
-    public MemberType getMemberType() {
-        return memberType;
-    }
-    
     @Override
     public R with(SpecAndFeature<T> specAndFeature) {
         objectSpecification = specAndFeature.getObjectSpecification();
         objectFeature = specAndFeature.getObjectFeature();
-        memberType = MemberType.determineFrom(objectFeature);
         
-        // done eagerly so can use as criteria for x-ro-follow-links
-        putIdIfMember();
-        putMemberTypeIfMember();
+        return cast(this);
+    }
 
+    public R withParent(ObjectSpecification parentSpec) {
+        this.parentSpec = parentSpec;
         return cast(this);
     }
 
-    protected void putIdIfMember() {
-        if(memberType == null) {
-            return;
-        } 
-        ObjectMember objectMember = (ObjectMember) objectFeature;
-        representation.mapPut(memberType.getJsProp(), objectMember.getId());
+    public JsonRepresentation render() {
+        
+        addLinkSelfIfRequired();
+        addLinkToParentIfProvided();
+        
+        addLinksSpecificToFeature();
+        putExtensionsSpecificToFeature();
+
+        return representation;
     }
 
-    protected void putMemberTypeIfMember() {
-        if(memberType == null) {
-            return;
-        } 
-        representation.mapPut("memberType", memberType.getName());
+    
+    /**
+     * Mandatory hook method.
+     */
+    protected abstract void addLinkSelfIfRequired();
+
+    /**
+     * Mandatory hook method.
+     */
+    protected abstract void addLinkToParentIfProvided();
+
+    /**
+     * Optional hook method.
+     */
+    protected void addLinksSpecificToFeature() {
     }
 
+    /**
+     * Mandatory hook method.
+     */
+    protected abstract void putExtensionsSpecificToFeature();
+
     
-    protected void includeSelfIfRequired() {
-        if(!includesSelf) {
-            return;
-        } 
-        
-        final ObjectMember objectMember = (ObjectMember)getObjectFeature();
-        final LinkBuilder linkBuilder = LinkBuilder.newBuilder(
-                getResourceContext(), Rel.SELF, getRepresentationType(), 
-                "domainTypes/%s/%s/%s", 
-                getObjectSpecification().getFullIdentifier(), 
-                getMemberType().getUrlPart(), 
-                objectMember.getId());
-        getLinks().arrayAdd(linkBuilder.build());
+    protected void putExtensionsName() {
+        String friendlyName = getObjectFeature().getName();
+        getExtensions().mapPut("friendlyName", friendlyName);
     }
 
+    protected void putExtensionsDescriptionIfAvailable() {
+        String description = getObjectFeature().getDescription();
+        if(!Strings.isNullOrEmpty(description)) {
+            getExtensions().mapPut("description", description);
+        }
+    }
+
+
 }
\ No newline at end of file

Added: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/AbstractTypeMemberReprBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/AbstractTypeMemberReprBuilder.java?rev=1188543&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/AbstractTypeMemberReprBuilder.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/AbstractTypeMemberReprBuilder.java Tue Oct 25 07:10:22 2011
@@ -0,0 +1,109 @@
+/**
+ *  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.json.viewer.resources.domaintypes;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.viewer.json.applib.JsonRepresentation;
+import org.apache.isis.viewer.json.applib.RepresentationType;
+import org.apache.isis.viewer.json.viewer.ResourceContext;
+import org.apache.isis.viewer.json.viewer.representations.LinkBuilder;
+import org.apache.isis.viewer.json.viewer.representations.LinkFollower;
+import org.apache.isis.viewer.json.viewer.representations.Rel;
+import org.apache.isis.viewer.json.viewer.representations.ReprRendererAbstract;
+import org.apache.isis.viewer.json.viewer.resources.domainobjects.MemberType;
+
+import com.google.common.base.Strings;
+
+public abstract class AbstractTypeMemberReprBuilder<R extends ReprRendererAbstract<R, SpecAndFeature<T>>, T extends ObjectMember> 
+        extends AbstractTypeFeatureReprBuilder<R, T> {
+
+    protected MemberType memberType;
+
+    public AbstractTypeMemberReprBuilder(ResourceContext resourceContext, LinkFollower linkFollower, RepresentationType representationType, JsonRepresentation representation) {
+        super(resourceContext, linkFollower, representationType, representation);
+    }
+
+    public ObjectSpecification getObjectSpecification() {
+        return objectSpecification;
+    }
+    
+    public T getObjectFeature() {
+        return objectFeature;
+    }
+
+    /**
+     * null if the feature is an object action param.
+     * @return
+     */
+    public MemberType getMemberType() {
+        return memberType;
+    }
+    
+    @Override
+    public R with(SpecAndFeature<T> specAndFeature) {
+        super.with(specAndFeature);
+        memberType = MemberType.determineFrom(objectFeature);
+        
+        // done eagerly so can use as criteria for x-ro-follow-links
+
+        if(memberType != null) {
+            ObjectMember objectMember = (ObjectMember) objectFeature;
+            putId(objectMember);
+            putMemberType(objectMember);
+        }
+
+        return cast(this);
+    }
+
+
+    protected void putId(ObjectMember objectMember) {
+        representation.mapPut(memberType.getJsProp(), objectMember.getId());
+    }
+
+    protected void putMemberType(ObjectMember objectMember) {
+        representation.mapPut("memberType", memberType.getName());
+    }
+
+    protected void addLinkToParentIfProvided() {
+        if(parentSpec == null) {
+            return;
+        }
+        final LinkBuilder parentLinkBuilder = 
+                DomainTypeReprRenderer.newLinkToBuilder(resourceContext, Rel.UP, parentSpec);
+        getLinks().arrayAdd(parentLinkBuilder.build());
+    }
+
+
+    protected void addLinkSelfIfRequired() {
+        if(!includesSelf) {
+            return;
+        } 
+        
+        final ObjectMember objectMember = (ObjectMember)getObjectFeature();
+        final LinkBuilder linkBuilder = LinkBuilder.newBuilder(
+                getResourceContext(), Rel.SELF, getRepresentationType(), 
+                "domainTypes/%s/%s%s", 
+                getObjectSpecification().getFullIdentifier(), 
+                getMemberType().getUrlPart(), 
+                objectMember.getId());
+        getLinks().arrayAdd(linkBuilder.build());
+    }
+    
+
+
+}
\ No newline at end of file

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeReprRenderer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeReprRenderer.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeReprRenderer.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeReprRenderer.java Tue Oct 25 07:10:22 2011
@@ -16,7 +16,15 @@
  */
 package org.apache.isis.viewer.json.viewer.resources.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.OneToOneActionParameter;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.viewer.json.applib.JsonRepresentation;
 import org.apache.isis.viewer.json.applib.RepresentationType;
 import org.apache.isis.viewer.json.viewer.ResourceContext;
@@ -27,6 +35,8 @@ import org.apache.isis.viewer.json.viewe
 import org.apache.isis.viewer.json.viewer.representations.ReprRendererAbstract;
 import org.apache.isis.viewer.json.viewer.representations.ReprRendererFactoryAbstract;
 
+import com.google.common.base.Strings;
+
 public class DomainTypeReprRenderer extends ReprRendererAbstract<DomainTypeReprRenderer, ObjectSpecification> {
 
     public static class Factory extends ReprRendererFactoryAbstract {
@@ -63,16 +73,58 @@ public class DomainTypeReprRenderer exte
 
         // self
         if(includesSelf) {
-            representation.mapPut("self", newLinkToBuilder(getResourceContext(), Rel.SELF, objectSpecification).build());
+            final JsonRepresentation selfLink = newLinkToBuilder(getResourceContext(), Rel.SELF, objectSpecification).build();
+            getLinks().arrayAdd(selfLink);
         }
         
-        
-        
-        // links and extensions
-        representation.mapPut("links", JsonRepresentation.newArray());
-        representation.mapPut("extensions", JsonRepresentation.newMap());
+        if(objectSpecification != null) {
+            representation.mapPut("canonicalName", objectSpecification.getFullIdentifier());
+            addMembers();
+
+            putExtensionsNames();
+            putExtensionsDescriptionIfAvailable();
+        }
 
         return representation;
     }
 
+    private void addMembers() {
+        final JsonRepresentation membersList = JsonRepresentation.newArray();
+        representation.mapPut("members", membersList);
+        final List<ObjectAssociation> associations = objectSpecification.getAssociations();
+        for (ObjectAssociation association : associations) {
+            if(association.isOneToOneAssociation()) {
+                OneToOneAssociation property = (OneToOneAssociation) association;
+                final LinkBuilder linkBuilder = TypePropertyReprRenderer.newLinkToBuilder(getResourceContext(), Rel.PROPERTY, objectSpecification, property);
+                membersList.arrayAdd(linkBuilder.build());
+            } else if(association.isOneToManyAssociation()) {
+                OneToManyAssociation collection = (OneToManyAssociation) association;
+                final LinkBuilder linkBuilder = TypeCollectionReprRenderer.newLinkToBuilder(getResourceContext(), Rel.PROPERTY, objectSpecification, collection);
+                membersList.arrayAdd(linkBuilder.build());
+            }
+        }
+        final List<ObjectAction> actions = objectSpecification.getObjectActions(Contributed.INCLUDED);
+        for (ObjectAction action : actions) {
+            final LinkBuilder linkBuilder = TypeActionReprRenderer.newLinkToBuilder(getResourceContext(), Rel.ACTION, objectSpecification, action);
+            membersList.arrayAdd(linkBuilder.build());
+        }
+        
+    }
+
+    
+    protected void putExtensionsNames() {
+        String singularName = objectSpecification.getSingularName();
+        getExtensions().mapPut("friendlyName", singularName);
+
+        String pluralName = objectSpecification.getPluralName();
+        getExtensions().mapPut("singularName", pluralName);
+    }
+
+    protected void putExtensionsDescriptionIfAvailable() {
+        String description = objectSpecification.getDescription();
+        if(!Strings.isNullOrEmpty(description)) {
+            getExtensions().mapPut("description", description);
+        }
+    }
+
 }
\ No newline at end of file

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeResourceServerside.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeResourceServerside.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeResourceServerside.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeResourceServerside.java Tue Oct 25 07:10:22 2011
@@ -97,12 +97,12 @@ public class DomainTypeResourceServersid
         RepresentationType representationType = RepresentationType.TYPE_PROPERTY;
         init(representationType);
 
-        final ObjectSpecification objectSpec = getSpecificationLoader().loadSpecification(domainType);
-        if(objectSpec == null) {
+        final ObjectSpecification parentSpec = getSpecificationLoader().loadSpecification(domainType);
+        if(parentSpec == null) {
             throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
         
-        final ObjectMember objectMember = objectSpec.getAssociation(propertyId);
+        final ObjectMember objectMember = parentSpec.getAssociation(propertyId);
         if(objectMember == null || objectMember.isOneToManyAssociation()) {
             throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
@@ -113,7 +113,7 @@ public class DomainTypeResourceServersid
         
         final TypePropertyReprRenderer renderer = 
                 (TypePropertyReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
-        renderer.with(new SpecAndProperty(objectSpec, property)).includesSelf();
+        renderer.with(new SpecAndProperty(parentSpec, property)).includesSelf().withParent(parentSpec);
 
         return responseOfOk(renderer, Caching.ONE_DAY).build();
     }
@@ -127,12 +127,12 @@ public class DomainTypeResourceServersid
         RepresentationType representationType = RepresentationType.TYPE_COLLECTION;
         init(representationType);
 
-        final ObjectSpecification objectSpec = getSpecificationLoader().loadSpecification(domainType);
-        if(objectSpec == null) {
+        final ObjectSpecification parentSpec = getSpecificationLoader().loadSpecification(domainType);
+        if(parentSpec == null) {
             throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
         
-        final ObjectMember objectMember = objectSpec.getAssociation(collectionId);
+        final ObjectMember objectMember = parentSpec.getAssociation(collectionId);
         if(objectMember == null || objectMember.isOneToOneAssociation()) {
             throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
@@ -143,7 +143,7 @@ public class DomainTypeResourceServersid
         
         final TypeCollectionReprRenderer renderer = 
                 (TypeCollectionReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
-        renderer.with(new SpecAndCollection(objectSpec, collection)).includesSelf();
+        renderer.with(new SpecAndCollection(parentSpec, collection)).includesSelf().withParent(parentSpec);
 
         return responseOfOk(renderer, Caching.ONE_DAY).build();
     }
@@ -157,12 +157,12 @@ public class DomainTypeResourceServersid
         RepresentationType representationType = RepresentationType.TYPE_ACTION;
         init(representationType);
 
-        final ObjectSpecification objectSpec = getSpecificationLoader().loadSpecification(domainType);
-        if(objectSpec == null) {
+        final ObjectSpecification parentSpec = getSpecificationLoader().loadSpecification(domainType);
+        if(parentSpec == null) {
             throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
         
-        final ObjectMember objectMember = objectSpec.getObjectAction(actionId);
+        final ObjectMember objectMember = parentSpec.getObjectAction(actionId);
         if(objectMember == null) {
             throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
@@ -173,7 +173,7 @@ public class DomainTypeResourceServersid
         
         final TypeActionReprRenderer renderer = 
                 (TypeActionReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
-        renderer.with(new SpecAndAction(objectSpec, action)).includesSelf();
+        renderer.with(new SpecAndAction(parentSpec, action)).includesSelf().withParent(parentSpec);
 
         return responseOfOk(renderer, Caching.ONE_DAY).build();
     }
@@ -188,25 +188,27 @@ public class DomainTypeResourceServersid
         RepresentationType representationType = RepresentationType.TYPE_ACTION_PARAMETER;
         init(representationType);
 
-        final ObjectSpecification objectSpec = getSpecificationLoader().loadSpecification(domainType);
-        if(objectSpec == null) {
+        final ObjectSpecification parentSpec = getSpecificationLoader().loadSpecification(domainType);
+        if(parentSpec == null) {
             throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
         
-        final ObjectMember objectMember = objectSpec.getObjectAction(actionId);
+        final ObjectMember objectMember = parentSpec.getObjectAction(actionId);
         if(objectMember == null) {
             throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND);
         }
-        ObjectAction action = (ObjectAction) objectMember;
+        ObjectAction parentAction = (ObjectAction) objectMember;
         
-        ObjectActionParameter actionParam = action.getParameter(paramName);
+        ObjectActionParameter actionParam = parentAction.getParameter(paramName);
 
         final RendererFactory rendererFactory = 
                 rendererFactoryRegistry.find(representationType);
         
         final TypeActionParamReprRenderer renderer = 
                 (TypeActionParamReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
-        renderer.with(new SpecAndActionParam(objectSpec, actionParam)).includesSelf();
+        renderer.with(new SpecAndActionParam(parentSpec, actionParam))
+                .includesSelf()
+                .withParent(parentSpec);
 
         return responseOfOk(renderer, Caching.ONE_DAY).build();
     }

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeActionParamReprRenderer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeActionParamReprRenderer.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeActionParamReprRenderer.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeActionParamReprRenderer.java Tue Oct 25 07:10:22 2011
@@ -30,6 +30,9 @@ import org.apache.isis.viewer.json.viewe
 
 public class TypeActionParamReprRenderer extends AbstractTypeFeatureReprBuilder<TypeActionParamReprRenderer, ObjectActionParameter> {
 
+    private ObjectAction parentAction;
+    private ObjectSpecification parentSpec;
+
     public static class Factory extends ReprRendererFactoryAbstract {
 
         public Factory() {
@@ -55,23 +58,30 @@ public class TypeActionParamReprRenderer
         super(resourceContext, linkFollower, representationType, representation);
     }
 
-
-    protected void includeSelfIfRequired() {
+    @Override
+    protected void addLinkSelfIfRequired() {
+        if(!includesSelf) {
+            return;
+        }
+        getLinks().arrayAdd( 
+                newLinkToBuilder(getResourceContext(), Rel.SELF, getObjectSpecification(), getObjectFeature()).build());
     }
 
-    public JsonRepresentation render() {
-
-        // self
-        if(includesSelf) {
-            representation.mapPut("self", 
-                newLinkToBuilder(getResourceContext(), Rel.SELF, getObjectSpecification(), getObjectFeature()).build());
+    @Override
+    protected void addLinkToParentIfProvided() {
+        if(parentSpec == null || parentAction == null) {
+            return;
         }
         
-        // links and extensions
-        representation.mapPut("links", JsonRepresentation.newArray());
-        representation.mapPut("extensions", JsonRepresentation.newMap());
+        final LinkBuilder parentLinkBuilder = 
+                TypeActionReprRenderer.newLinkToBuilder(resourceContext, Rel.UP, parentSpec, parentAction);
+        getLinks().arrayAdd(parentLinkBuilder.build());
+    }
 
-        return representation;
+    @Override
+    protected void putExtensionsSpecificToFeature() {
+        putExtensionsName();
+        putExtensionsDescriptionIfAvailable();        
     }
 
 

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeActionReprRenderer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeActionReprRenderer.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeActionReprRenderer.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeActionReprRenderer.java Tue Oct 25 07:10:22 2011
@@ -16,18 +16,24 @@
  */
 package org.apache.isis.viewer.json.viewer.resources.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.json.applib.JsonRepresentation;
 import org.apache.isis.viewer.json.applib.RepresentationType;
 import org.apache.isis.viewer.json.viewer.ResourceContext;
-import org.apache.isis.viewer.json.viewer.representations.LinkFollower;
 import org.apache.isis.viewer.json.viewer.representations.LinkBuilder;
+import org.apache.isis.viewer.json.viewer.representations.LinkFollower;
 import org.apache.isis.viewer.json.viewer.representations.Rel;
 import org.apache.isis.viewer.json.viewer.representations.ReprRenderer;
 import org.apache.isis.viewer.json.viewer.representations.ReprRendererFactoryAbstract;
 
-public class TypeActionReprRenderer extends AbstractTypeFeatureReprBuilder<TypeActionReprRenderer, ObjectAction> {
+import com.google.common.base.Strings;
+
+public class TypeActionReprRenderer extends AbstractTypeMemberReprBuilder<TypeActionReprRenderer, ObjectAction> {
 
     public static class Factory extends ReprRendererFactoryAbstract {
 
@@ -52,17 +58,50 @@ public class TypeActionReprRenderer exte
         super(resourceContext, linkFollower, representationType, representation);
     }
 
+    
+    @Override
+    protected void addLinksSpecificToFeature() {
+        addLinksForParameters();
+        addLinkToReturnTypeIfAny();
+        addLinkToElementTypeIfAny();
+    }
 
-    public JsonRepresentation render() {
+    private void addLinksForParameters() {
+        if(parentSpec == null) {
+            return;
+        }
+        final List<ObjectActionParameter> parameters = getObjectFeature().getParameters();
+        for (ObjectActionParameter parameter : parameters) {
+            final LinkBuilder linkBuilder = TypeActionParamReprRenderer.newLinkToBuilder(getResourceContext(), Rel.ACTION_PARAM, parentSpec, parameter);
+            getLinks().arrayAdd(linkBuilder.build());
+        }
+        
+    }
 
-        // self
-        includeSelfIfRequired();
+    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());
+    }
 
-        // links and extensions
-        representation.mapPut("links", JsonRepresentation.newArray());
-        representation.mapPut("extensions", JsonRepresentation.newMap());
+    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());
+    }
 
-        return representation;
+    @Override
+    protected void putExtensionsSpecificToFeature() {
+        putExtensionsName();
+        putExtensionsDescriptionIfAvailable();
     }
 
 

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeCollectionReprRenderer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeCollectionReprRenderer.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeCollectionReprRenderer.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeCollectionReprRenderer.java Tue Oct 25 07:10:22 2011
@@ -27,7 +27,7 @@ import org.apache.isis.viewer.json.viewe
 import org.apache.isis.viewer.json.viewer.representations.ReprRenderer;
 import org.apache.isis.viewer.json.viewer.representations.ReprRendererFactoryAbstract;
 
-public class TypeCollectionReprRenderer extends AbstractTypeFeatureReprBuilder<TypeCollectionReprRenderer, OneToManyAssociation> {
+public class TypeCollectionReprRenderer extends AbstractTypeMemberReprBuilder<TypeCollectionReprRenderer, OneToManyAssociation> {
 
     public static class Factory extends ReprRendererFactoryAbstract {
 
@@ -52,16 +52,27 @@ public class TypeCollectionReprRenderer 
         super(resourceContext, linkFollower, representationType, representation);
     }
 
-    public JsonRepresentation render() {
-
-        includeSelfIfRequired();
+    @Override
+    protected void addLinksSpecificToFeature() {
+        addLinkToElementTypeIfAny();
+    }
 
-        // links and extensions
-        representation.mapPut("links", JsonRepresentation.newArray());
-        representation.mapPut("extensions", JsonRepresentation.newMap());
+    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());
+    }
 
-        return representation;
+    @Override
+    protected void putExtensionsSpecificToFeature() {
+        putExtensionsName();
+        putExtensionsDescriptionIfAvailable();
     }
 
 
+
 }
\ No newline at end of file

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypePropertyReprRenderer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypePropertyReprRenderer.java?rev=1188543&r1=1188542&r2=1188543&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypePropertyReprRenderer.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypePropertyReprRenderer.java Tue Oct 25 07:10:22 2011
@@ -27,7 +27,7 @@ import org.apache.isis.viewer.json.viewe
 import org.apache.isis.viewer.json.viewer.representations.ReprRenderer;
 import org.apache.isis.viewer.json.viewer.representations.ReprRendererFactoryAbstract;
 
-public class TypePropertyReprRenderer extends AbstractTypeFeatureReprBuilder<TypePropertyReprRenderer, OneToOneAssociation> {
+public class TypePropertyReprRenderer extends AbstractTypeMemberReprBuilder<TypePropertyReprRenderer, OneToOneAssociation> {
 
     public static class Factory extends ReprRendererFactoryAbstract {
 
@@ -52,16 +52,26 @@ public class TypePropertyReprRenderer ex
         super(resourceContext, linkFollower, representationType, representation);
     }
 
-    public JsonRepresentation render() {
-        
-        // self
-        includeSelfIfRequired();
-
-        // links and extensions
-        representation.mapPut("links", JsonRepresentation.newArray());
-        representation.mapPut("extensions", JsonRepresentation.newMap());
+    @Override
+    protected void addLinksSpecificToFeature() {
+        addLinkToReturnTypeIfAny();
+    }
+
+    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());
+    }
+
 
-        return representation;
+    @Override
+    protected void putExtensionsSpecificToFeature() {
+        putExtensionsName();
+        putExtensionsDescriptionIfAvailable();
     }