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 14:16:19 UTC
[7/24] ISIS-323: lots more refactoring of RO
http://git-wip-us.apache.org/repos/asf/isis/blob/75f41b75/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndProperty.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndProperty.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndProperty.java
new file mode 100644
index 0000000..0b9a236
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndProperty.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.domainobjects;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+
+public class ObjectAndProperty extends ObjectAndMember<OneToOneAssociation> {
+
+ public ObjectAndProperty(final ObjectAdapter objectAdapter, final OneToOneAssociation property) {
+ super(objectAdapter, property);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/75f41b75/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
new file mode 100644
index 0000000..8dd36c9
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
@@ -0,0 +1,157 @@
+/**
+ * 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 java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacetUtils;
+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.RendererFactory;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererFactoryRegistry;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererFactoryAbstract;
+import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.CollectionDescriptionReprRenderer;
+
+import com.google.common.collect.Lists;
+
+public class ObjectCollectionReprRenderer extends AbstractObjectMemberReprRenderer<ObjectCollectionReprRenderer, OneToManyAssociation> {
+
+ public static class Factory extends ReprRendererFactoryAbstract {
+
+ public Factory() {
+ super(RepresentationType.OBJECT_COLLECTION);
+ }
+
+ @Override
+ public ReprRenderer<?, ?> newRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final JsonRepresentation representation) {
+ return new ObjectCollectionReprRenderer(resourceContext, linkFollower, getRepresentationType(), representation);
+ }
+ }
+
+ private ObjectCollectionReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+ super(resourceContext, linkFollower, representationType, representation, Where.PARENTED_TABLES);
+ }
+
+ @Override
+ public JsonRepresentation render() {
+ // id and memberType are rendered eagerly
+
+ renderMemberContent();
+ if (mode.isStandalone() || mode.isMutated() || !objectAdapter.representsPersistent()) {
+ addValue();
+ }
+ putDisabledReasonIfDisabled();
+
+ if (mode.isStandalone() || mode.isMutated()) {
+ addExtensionsIsisProprietaryChangedObjects();
+ }
+
+ return representation;
+ }
+
+ // ///////////////////////////////////////////////////
+ // value
+ // ///////////////////////////////////////////////////
+
+ private void addValue() {
+ final ObjectAdapter valueAdapter = objectMember.get(objectAdapter);
+ if (valueAdapter == null) {
+ return;
+ }
+
+ final CollectionFacet facet = CollectionFacetUtils.getCollectionFacetFromSpec(valueAdapter);
+ final List<JsonRepresentation> list = Lists.newArrayList();
+ for (final ObjectAdapter elementAdapter : facet.iterable(valueAdapter)) {
+
+ final LinkBuilder newBuilder = DomainObjectReprRenderer.newLinkToBuilder(resourceContext, Rel.OBJECT, elementAdapter);
+
+ list.add(newBuilder.build());
+ }
+
+ representation.mapPut("value", list);
+ }
+
+ // ///////////////////////////////////////////////////
+ // details link
+ // ///////////////////////////////////////////////////
+
+ /**
+ * Mandatory hook method to support x-ro-follow-links
+ */
+ @Override
+ protected void followDetailsLink(final JsonRepresentation detailsLink) {
+ final RendererFactory factory = RendererFactoryRegistry.instance.find(RepresentationType.OBJECT_COLLECTION);
+ final ObjectCollectionReprRenderer renderer = (ObjectCollectionReprRenderer) factory.newRenderer(getResourceContext(), getLinkFollower(), JsonRepresentation.newMap());
+ renderer.with(new ObjectAndCollection(objectAdapter, objectMember)).asFollowed();
+ detailsLink.mapPut("value", renderer.render());
+ }
+
+ // ///////////////////////////////////////////////////
+ // mutators
+ // ///////////////////////////////////////////////////
+
+ @Override
+ protected void addMutatorsIfEnabled() {
+ if (usability().isVetoed()) {
+ return;
+ }
+
+ final CollectionSemantics semantics = CollectionSemantics.determine(objectMember);
+ addMutatorLink(semantics.getAddToKey());
+ addMutatorLink(semantics.getRemoveFromKey());
+
+ return;
+ }
+
+ private void addMutatorLink(final String key) {
+ final Map<String, MutatorSpec> mutators = memberType.getMutators();
+ final MutatorSpec mutatorSpec = mutators.get(key);
+ addLinkFor(mutatorSpec);
+ }
+
+ // ///////////////////////////////////////////////////
+ // extensions and links
+ // ///////////////////////////////////////////////////
+
+ @Override
+ protected void addLinksToFormalDomainModel() {
+ final LinkBuilder linkBuilder = CollectionDescriptionReprRenderer.newLinkToBuilder(resourceContext, Rel.DESCRIBEDBY, objectAdapter.getSpecification(), objectMember);
+ getLinks().arrayAdd(linkBuilder.build());
+ }
+
+ @Override
+ protected void addLinksIsisProprietary() {
+ // none
+ }
+
+ @Override
+ protected void putExtensionsIsisProprietary() {
+ final CollectionSemantics semantics = CollectionSemantics.determine(objectMember);
+ getExtensions().mapPut("collectionSemantics", semantics.name().toLowerCase());
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/75f41b75/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
new file mode 100644
index 0000000..2c1c6c1
--- /dev/null
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
@@ -0,0 +1,167 @@
+/**
+ * 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 java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+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.LinkFollower;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererFactory;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererFactoryRegistry;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererFactoryAbstract;
+import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.PropertyDescriptionReprRenderer;
+import org.codehaus.jackson.node.NullNode;
+
+import com.google.common.collect.Lists;
+
+public class ObjectPropertyReprRenderer extends AbstractObjectMemberReprRenderer<ObjectPropertyReprRenderer, OneToOneAssociation> {
+
+ public static class Factory extends ReprRendererFactoryAbstract {
+
+ public Factory() {
+ super(RepresentationType.OBJECT_PROPERTY);
+ }
+
+ @Override
+ public ReprRenderer<?, ?> newRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final JsonRepresentation representation) {
+ return new ObjectPropertyReprRenderer(resourceContext, linkFollower, getRepresentationType(), representation);
+ }
+ }
+
+ private ObjectPropertyReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+ super(resourceContext, linkFollower, representationType, representation, Where.OBJECT_FORMS);
+ }
+
+ @Override
+ public JsonRepresentation render() {
+ // id and memberType are rendered eagerly
+
+ renderMemberContent();
+ addValue();
+
+ putDisabledReasonIfDisabled();
+
+ if (mode.isStandalone() || mode.isMutated()) {
+ addChoices();
+ addExtensionsIsisProprietaryChangedObjects();
+ }
+
+ return representation;
+ }
+
+ // ///////////////////////////////////////////////////
+ // value
+ // ///////////////////////////////////////////////////
+
+ private void addValue() {
+ representation.mapPut("value", valueRep());
+ }
+
+ private Object valueRep() {
+ final ObjectAdapter valueAdapter = objectMember.get(objectAdapter);
+ if (valueAdapter == null) {
+ return NullNode.getInstance();
+ }
+ return DomainObjectReprRenderer.valueOrRef(resourceContext, valueAdapter, objectMember.getSpecification());
+ }
+
+ // ///////////////////////////////////////////////////
+ // details link
+ // ///////////////////////////////////////////////////
+
+ /**
+ * Mandatory hook method to support x-ro-follow-links
+ */
+ @Override
+ protected void followDetailsLink(final JsonRepresentation detailsLink) {
+ final RendererFactory factory = RendererFactoryRegistry.instance.find(RepresentationType.OBJECT_PROPERTY);
+ final ObjectPropertyReprRenderer renderer = (ObjectPropertyReprRenderer) factory.newRenderer(getResourceContext(), getLinkFollower(), JsonRepresentation.newMap());
+ renderer.with(new ObjectAndProperty(objectAdapter, objectMember)).asFollowed();
+ detailsLink.mapPut("value", renderer.render());
+ }
+
+ // ///////////////////////////////////////////////////
+ // mutators
+ // ///////////////////////////////////////////////////
+
+ @Override
+ protected void addMutatorsIfEnabled() {
+ if (usability().isVetoed()) {
+ return;
+ }
+ final Map<String, MutatorSpec> mutators = memberType.getMutators();
+ for (final String mutator : mutators.keySet()) {
+ final MutatorSpec mutatorSpec = mutators.get(mutator);
+ addLinkFor(mutatorSpec);
+ }
+ return;
+ }
+
+ // ///////////////////////////////////////////////////
+ // choices
+ // ///////////////////////////////////////////////////
+
+ private ObjectPropertyReprRenderer addChoices() {
+ final Object propertyChoices = propertyChoices();
+ if (propertyChoices != null) {
+ representation.mapPut("choices", propertyChoices);
+ }
+ return this;
+ }
+
+ private Object propertyChoices() {
+ final ObjectAdapter[] choiceAdapters = objectMember.getChoices(objectAdapter);
+ if (choiceAdapters == null || choiceAdapters.length == 0) {
+ return null;
+ }
+ final List<Object> list = Lists.newArrayList();
+ for (final ObjectAdapter choiceAdapter : choiceAdapters) {
+ final ObjectSpecification objectSpec = objectMember.getSpecification();
+ list.add(DomainObjectReprRenderer.valueOrRef(resourceContext, choiceAdapter, objectSpec));
+ }
+ return list;
+ }
+
+ // ///////////////////////////////////////////////////
+ // extensions and links
+ // ///////////////////////////////////////////////////
+
+ @Override
+ protected void addLinksToFormalDomainModel() {
+ getLinks().arrayAdd(PropertyDescriptionReprRenderer.newLinkToBuilder(getResourceContext(), Rel.DESCRIBEDBY, objectAdapter.getSpecification(), objectMember).build());
+ }
+
+ @Override
+ protected void addLinksIsisProprietary() {
+ // none
+ }
+
+ @Override
+ protected void putExtensionsIsisProprietary() {
+ // none
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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/75f41b75/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);
+ }
+
+}