You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2013/02/08 19:29:52 UTC

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

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/CollectionSemantics.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/CollectionSemantics.java b/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/CollectionSemantics.java
deleted file mode 100644
index 0d29c28..0000000
--- a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/CollectionSemantics.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  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.viewer.resources.domainobjects;
-
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-
-public enum CollectionSemantics {
-
-    SET("addToSet"), LIST("addToList");
-
-    private final String addToKey;
-
-    private CollectionSemantics(final String addToKey) {
-        this.addToKey = addToKey;
-    }
-
-    public String getAddToKey() {
-        return addToKey;
-    }
-
-    public String getRemoveFromKey() {
-        return "removeFrom";
-    }
-
-    public static CollectionSemantics determine(final OneToManyAssociation collection) {
-        return collection.getCollectionSemantics().isSet() ? CollectionSemantics.SET : CollectionSemantics.LIST;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectLinkTo.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectLinkTo.java b/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectLinkTo.java
deleted file mode 100644
index a4f7f1e..0000000
--- a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectLinkTo.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- *  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.viewer.resources.domainobjects;
-
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
-import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.isis.viewer.restfulobjects.applib.links.Rel;
-import org.apache.isis.viewer.restfulobjects.viewer.RendererContext;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.LinkBuilder;
-
-public class DomainObjectLinkTo implements ObjectAdapterLinkTo {
-
-    protected RendererContext resourceContext;
-    protected ObjectAdapter objectAdapter;
-
-    @Override
-    public final DomainObjectLinkTo usingUrlBase(final RendererContext resourceContext) {
-        this.resourceContext = resourceContext;
-        return this;
-    }
-
-    @Override
-    public ObjectAdapterLinkTo with(final ObjectAdapter objectAdapter) {
-        this.objectAdapter = objectAdapter;
-        return this;
-    }
-
-    @Override
-    public LinkBuilder builder() {
-        return builder(null);
-    }
-
-    @Override
-    public LinkBuilder builder(final Rel rel) {
-        final LinkBuilder linkBuilder = LinkBuilder.newBuilder(resourceContext, relElseDefault(rel), RepresentationType.DOMAIN_OBJECT, linkRef());
-        linkBuilder.withTitle(objectAdapter.titleString());
-        return linkBuilder;
-    }
-
-    /**
-     * hook method
-     */
-    protected String linkRef() {
-        if (resourceContext == null) {
-            throw new IllegalStateException("resourceContext not provided");
-        }
-        if (objectAdapter == null) {
-            throw new IllegalStateException("objectAdapter not provided");
-        }
-        final StringBuilder buf = new StringBuilder("objects/");
-        buf.append(objectAdapter.getOid().enString(getOidMarshaller()));
-        return buf.toString();
-    }
-
-    private Rel relElseDefault(final Rel rel) {
-        return rel != null ? rel : defaultRel();
-    }
-
-    /**
-     * hook method; used by {@link #builder(Rel)}.
-     */
-    protected Rel defaultRel() {
-        return Rel.OBJECT;
-    }
-
-    @Override
-    public final LinkBuilder memberBuilder(final Rel rel, final MemberType memberType, final ObjectMember objectMember, final String... parts) {
-        return memberBuilder(rel, memberType, objectMember, memberType.getRepresentationType(), parts);
-    }
-
-    @Override
-    public final LinkBuilder memberBuilder(final Rel rel, final MemberType memberType, final ObjectMember objectMember, final RepresentationType representationType, final String... parts) {
-        final StringBuilder buf = new StringBuilder(linkRef());
-        buf.append("/").append(memberType.getUrlPart()).append(objectMember.getId());
-        for (final String part : parts) {
-            if (part == null) {
-                continue;
-            }
-            buf.append("/").append(part);
-        }
-        final String url = buf.toString();
-        return LinkBuilder.newBuilder(resourceContext, rel, representationType, url);
-    }
-
-
-    
-    //////////////////////////////////////////////////
-    // Dependencies (from context)
-    //////////////////////////////////////////////////
-    
-    protected static OidMarshaller getOidMarshaller() {
-        return IsisContext.getOidMarshaller();
-    }
-
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectReprRenderer.java b/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectReprRenderer.java
deleted file mode 100644
index e4ab923..0000000
--- a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectReprRenderer.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/**
- *  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.viewer.resources.domainobjects;
-
-import java.util.List;
-
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
-import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
-import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
-import org.apache.isis.core.metamodel.services.ServiceUtil;
-import org.apache.isis.core.metamodel.spec.ObjectActionSet;
-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.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.restfulobjects.applib.HttpMethod;
-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.viewer.RendererContext;
-import org.apache.isis.viewer.restfulobjects.viewer.ResourceContext;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.LinkBuilder;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.LinkFollower;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.RendererFactory;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.RendererFactoryRegistry;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.ReprRenderer;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.ReprRendererAbstract;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.ReprRendererFactoryAbstract;
-import org.apache.isis.viewer.restfulobjects.viewer.resources.domaintypes.DomainTypeReprRenderer;
-import org.apache.isis.viewer.restfulobjects.viewer.util.OidUtils;
-
-public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectReprRenderer, ObjectAdapter> {
-
-    public static class Factory extends ReprRendererFactoryAbstract {
-
-        public Factory() {
-            super(RepresentationType.DOMAIN_OBJECT);
-        }
-
-        @Override
-        public ReprRenderer<?, ?> newRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final JsonRepresentation representation) {
-            return new DomainObjectReprRenderer(resourceContext, linkFollower, getRepresentationType(), representation);
-        }
-    }
-
-    public static LinkBuilder newLinkToBuilder(final RendererContext resourceContext, final Rel rel, final ObjectAdapter elementAdapter) {
-        final String oidStr = ((RootOid) elementAdapter.getOid()).enString(getOidMarshaller());
-        final String url = "objects/" + oidStr;
-        final LinkBuilder builder = LinkBuilder.newBuilder(resourceContext, rel, RepresentationType.DOMAIN_OBJECT, url).withTitle(elementAdapter.titleString());
-        return builder;
-    }
-
-    private static enum Mode {
-        REGULAR(false, true), PERSIST_LINK_ARGUMENTS(true, true), MODIFY_PROPERTIES_LINK_ARGUMENTS(true, false);
-
-        private final boolean cutDown;
-        private final boolean describedBy;
-
-        private Mode(final boolean cutDown, final boolean describedBy) {
-            this.cutDown = cutDown;
-            this.describedBy = describedBy;
-        }
-
-        public boolean isCutDown() {
-            return cutDown;
-        }
-
-        public boolean includesDescribedBy() {
-            return describedBy;
-        }
-    }
-
-    private ObjectAdapterLinkTo linkToBuilder;
-    private ObjectAdapter objectAdapter;
-    private Mode mode = Mode.REGULAR;
-
-    private DomainObjectReprRenderer(final RendererContext resourceContext, final LinkFollower linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
-        super(resourceContext, linkFollower, representationType, representation);
-        usingLinkToBuilder(new DomainObjectLinkTo());
-    }
-
-    /**
-     * Override the default {@link ObjectAdapterLinkTo} (that is used for
-     * generating links in {@link #linkTo(ObjectAdapter)}).
-     */
-    public DomainObjectReprRenderer usingLinkToBuilder(final ObjectAdapterLinkTo objectAdapterLinkToBuilder) {
-        this.linkToBuilder = objectAdapterLinkToBuilder.usingUrlBase(resourceContext);
-        return this;
-    }
-
-    @Override
-    public DomainObjectReprRenderer with(final ObjectAdapter objectAdapter) {
-        this.objectAdapter = objectAdapter;
-        return this;
-    }
-
-    @Override
-    public JsonRepresentation render() {
-
-        // self, oid
-        if (!mode.isCutDown()) {
-            if (objectAdapter.representsPersistent()) {
-                if (includesSelf) {
-                    final JsonRepresentation self = linkToBuilder.with(objectAdapter).builder(Rel.SELF).build();
-                    getLinks().arrayAdd(self);
-                }
-                representation.mapPut("oid", getOidStr());
-            }
-        }
-
-        // title
-        if (!mode.isCutDown()) {
-            final String title = objectAdapter.titleString();
-            representation.mapPut("title", title);
-
-        }
-
-        // serviceId
-        if (!mode.isCutDown()) {
-            final boolean isService = objectAdapter.getSpecification().isService();
-            if (isService) {
-                representation.mapPut("serviceId", ServiceUtil.id(objectAdapter.getObject()));
-            }
-        }
-
-        // members
-        withMembers(objectAdapter);
-
-        // described by
-        if (mode.includesDescribedBy()) {
-            getLinks().arrayAdd(DomainTypeReprRenderer.newLinkToBuilder(getResourceContext(), Rel.DESCRIBEDBY, objectAdapter.getSpecification()).build());
-        }
-
-        if (!mode.isCutDown()) {
-            // update/persist
-            addPersistLinkIfTransient();
-            addUpdatePropertiesLinkIfPersistent();
-
-            // extensions
-            final boolean isService = objectAdapter.getSpecification().isService();
-            getExtensions().mapPut("isService", isService);
-            getExtensions().mapPut("isPersistent", objectAdapter.representsPersistent());
-        }
-
-        return representation;
-    }
-
-    private String getOidStr() {
-        return OidUtils.getOidStr(resourceContext, objectAdapter);
-    }
-
-    private DomainObjectReprRenderer withMembers(final ObjectAdapter objectAdapter) {
-        final JsonRepresentation members = JsonRepresentation.newArray();
-        final List<ObjectAssociation> associations = objectAdapter.getSpecification().getAssociations();
-        addAssociations(objectAdapter, members, associations);
-
-        if (!mode.isCutDown()) {
-            final List<ObjectAction> actions = objectAdapter.getSpecification().getObjectActions(Contributed.INCLUDED);
-            addActions(objectAdapter, actions, members);
-        }
-        representation.mapPut("members", members);
-        return this;
-    }
-
-    private void addAssociations(final ObjectAdapter objectAdapter, final JsonRepresentation members, final List<ObjectAssociation> associations) {
-        final LinkFollower linkFollower = getLinkFollower().follow("members");
-        for (final ObjectAssociation assoc : associations) {
-
-            if (!mode.isCutDown()) {
-                final Consent visibility = assoc.isVisible(getSession(), objectAdapter, resourceContext.getWhere());
-                if (!visibility.isAllowed()) {
-                    continue;
-                }
-            }
-            if (assoc instanceof OneToOneAssociation) {
-                final OneToOneAssociation property = (OneToOneAssociation) assoc;
-
-                final RendererFactory factory = getRendererFactoryRegistry().find(RepresentationType.OBJECT_PROPERTY);
-                final ObjectPropertyReprRenderer renderer = (ObjectPropertyReprRenderer) factory.newRenderer(getResourceContext(), linkFollower, JsonRepresentation.newMap());
-
-                renderer.with(new ObjectAndProperty(objectAdapter, property)).usingLinkTo(linkToBuilder);
-
-                if (mode.isCutDown()) {
-                    renderer.asArguments();
-                }
-
-                members.arrayAdd(renderer.render());
-            }
-
-            if (mode.isCutDown()) {
-                // don't include collections
-                continue;
-            }
-            if (assoc instanceof OneToManyAssociation) {
-                final OneToManyAssociation collection = (OneToManyAssociation) assoc;
-
-                final RendererFactory factory = getRendererFactoryRegistry().find(RepresentationType.OBJECT_COLLECTION);
-                final ObjectCollectionReprRenderer renderer = (ObjectCollectionReprRenderer) factory.newRenderer(getResourceContext(), linkFollower, JsonRepresentation.newMap());
-
-                renderer.with(new ObjectAndCollection(objectAdapter, collection)).usingLinkTo(linkToBuilder);
-
-                members.arrayAdd(renderer.render());
-            }
-        }
-    }
-
-    private void addActions(final ObjectAdapter objectAdapter, final List<ObjectAction> actions, final JsonRepresentation members) {
-        final LinkFollower linkFollower = getLinkFollower().follow("members");
-        for (final ObjectAction action : actions) {
-            final Consent visibility = action.isVisible(getSession(), objectAdapter, resourceContext.getWhere());
-            if (!visibility.isAllowed()) {
-                continue;
-            }
-            if (action.getType().isSet()) {
-                final ObjectActionSet objectActionSet = (ObjectActionSet) action;
-                final List<ObjectAction> subactions = objectActionSet.getActions();
-                addActions(objectAdapter, subactions, members);
-
-            } else {
-
-                final RendererFactory factory = getRendererFactoryRegistry().find(RepresentationType.OBJECT_ACTION);
-                final ObjectActionReprRenderer renderer = (ObjectActionReprRenderer) factory.newRenderer(getResourceContext(), linkFollower, JsonRepresentation.newMap());
-
-                renderer.with(new ObjectAndAction(objectAdapter, action)).usingLinkTo(linkToBuilder);
-
-                members.arrayAdd(renderer.render());
-            }
-        }
-    }
-
-    private void addPersistLinkIfTransient() {
-        if (objectAdapter.representsPersistent()) {
-            return;
-        }
-        final RendererFactory rendererFactory = getRendererFactoryRegistry().find(RepresentationType.DOMAIN_OBJECT);
-        final DomainObjectReprRenderer renderer = (DomainObjectReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
-        final JsonRepresentation domainObjectRepr = renderer.with(objectAdapter).asPersistLinkArguments().render();
-
-        final LinkBuilder persistLinkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.PERSIST, RepresentationType.DOMAIN_OBJECT, "objects/").withHttpMethod(HttpMethod.POST).withArguments(domainObjectRepr);
-        getLinks().arrayAdd(persistLinkBuilder.build());
-    }
-
-    private DomainObjectReprRenderer asPersistLinkArguments() {
-        this.mode = Mode.PERSIST_LINK_ARGUMENTS;
-        return this;
-    }
-
-    private DomainObjectReprRenderer asModifyPropertiesLinkArguments() {
-        this.mode = Mode.MODIFY_PROPERTIES_LINK_ARGUMENTS;
-        return this;
-    }
-
-    private void addUpdatePropertiesLinkIfPersistent() {
-        if (!objectAdapter.representsPersistent()) {
-            return;
-        }
-
-        final RendererFactory rendererFactory = getRendererFactoryRegistry().find(RepresentationType.DOMAIN_OBJECT);
-        final DomainObjectReprRenderer renderer = (DomainObjectReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
-        final JsonRepresentation domainObjectRepr = renderer.with(objectAdapter).asModifyPropertiesLinkArguments().render();
-
-        final LinkBuilder persistLinkBuilder = LinkBuilder.newBuilder(getResourceContext(), Rel.MODIFY, RepresentationType.DOMAIN_OBJECT, "objects/%s", getOidStr()).withHttpMethod(HttpMethod.PUT).withArguments(domainObjectRepr);
-        getLinks().arrayAdd(persistLinkBuilder.build());
-    }
-
-    protected RendererFactoryRegistry getRendererFactoryRegistry() {
-        return RendererFactoryRegistry.instance;
-    }
-
-    // ///////////////////////////////////////////////////////////////////
-    //
-    // ///////////////////////////////////////////////////////////////////
-
-    public static Object valueOrRef(final RendererContext resourceContext, final ObjectAdapter objectAdapter, final ObjectSpecification objectSpec) {
-        final ValueFacet valueFacet = objectSpec.getFacet(ValueFacet.class);
-        if (valueFacet != null) {
-            return new JsonValueEncoder().asObject(objectAdapter);
-        }
-        final TitleFacet titleFacet = objectSpec.getFacet(TitleFacet.class);
-        final String title = titleFacet.title(objectAdapter, resourceContext.getLocalization());
-        return DomainObjectReprRenderer.newLinkToBuilder(resourceContext, Rel.OBJECT, objectAdapter).withTitle(title).build();
-    }
-
- 
-    
-    // ///////////////////////////////////////////////////////////////////
-    // dependencies (from context)
-    // ///////////////////////////////////////////////////////////////////
-
-    protected static OidMarshaller getOidMarshaller() {
-		return IsisContext.getOidMarshaller();
-	}
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectResourceServerside.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectResourceServerside.java b/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectResourceServerside.java
deleted file mode 100644
index 8497fe9..0000000
--- a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainObjectResourceServerside.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/**
- *  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.viewer.resources.domainobjects;
-
-import java.io.InputStream;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.jboss.resteasy.annotations.ClientResponseType;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
-import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
-import org.apache.isis.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
-import org.apache.isis.viewer.restfulobjects.applib.links.LinkRepresentation;
-import org.apache.isis.viewer.restfulobjects.domainobjects.DomainObjectResource;
-import org.apache.isis.viewer.restfulobjects.viewer.RestfulObjectsApplicationException;
-import org.apache.isis.viewer.restfulobjects.viewer.resources.ResourceAbstract;
-import org.apache.isis.viewer.restfulobjects.viewer.resources.domainobjects.DomainResourceHelper.Intent;
-import org.apache.isis.viewer.restfulobjects.viewer.resources.domainobjects.DomainResourceHelper.MemberMode;
-import org.apache.isis.viewer.restfulobjects.viewer.util.UrlParserUtils;
-
-@Path("/objects")
-public class DomainObjectResourceServerside extends ResourceAbstract implements DomainObjectResource {
-
-    // //////////////////////////////////////////////////////////
-    // persist
-    // //////////////////////////////////////////////////////////
-
-    @Override
-    @POST
-    @Path("/")
-    @Consumes({ MediaType.WILDCARD })
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_DOMAIN_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR })
-    @ClientResponseType(entityType = String.class)
-    public Response persist(final InputStream object) {
-
-        init(RepresentationType.DOMAIN_OBJECT, Where.OBJECT_FORMS);
-
-        final String objectStr = DomainResourceHelper.asStringUtf8(object);
-        final JsonRepresentation objectRepr = DomainResourceHelper.readAsMap(objectStr);
-        if (!objectRepr.isMap()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Body is not a map; got %s", objectRepr);
-        }
-
-        final LinkRepresentation describedByLink = objectRepr.getLink("links[rel=describedby]");
-        if (!describedByLink.isLink()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Could not determine type of domain object to persist (no links[rel=describedby] link); got %s", objectRepr);
-        }
-
-        final String domainTypeStr = UrlParserUtils.domainTypeFrom(describedByLink);
-        if (domainTypeStr == null) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Could not determine type of domain object to persist (no href in links[rel=describedby]); got %s", describedByLink);
-        }
-        final ObjectSpecification domainTypeSpec = getSpecificationLoader().loadSpecification(domainTypeStr);
-        if (domainTypeSpec == null) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Could not determine type of domain object to persist (no such class '%s')", domainTypeStr);
-        }
-
-        final ObjectAdapter objectAdapter = getResourceContext().getPersistenceSession().createTransientInstance(domainTypeSpec);
-
-        final JsonRepresentation propertiesList = objectRepr.getArrayEnsured("members[memberType=property]");
-        if (propertiesList == null) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Could not find properties list (no members[memberType=property]); got %s", objectRepr);
-        }
-        if (!DomainResourceHelper.copyOverProperties(getResourceContext(), objectAdapter, propertiesList)) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, objectRepr, "Illegal property value");
-        }
-
-        final Consent validity = objectAdapter.getSpecification().isValid(objectAdapter);
-        if (validity.isVetoed()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, objectRepr, validity.getReason());
-        }
-        getResourceContext().getPersistenceSession().makePersistent(objectAdapter);
-
-        return new DomainResourceHelper(getResourceContext(), objectAdapter).objectRepresentation();
-    }
-
-    // //////////////////////////////////////////////////////////
-    // domain object
-    // //////////////////////////////////////////////////////////
-
-    @Override
-    @GET
-    @Path("/{oid}")
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_DOMAIN_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response object(@PathParam("oid") final String oidStr) {
-        init(RepresentationType.DOMAIN_OBJECT, Where.OBJECT_FORMS);
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-        return helper.objectRepresentation();
-    }
-
-    @Override
-    @PUT
-    @Path("/{oid}")
-    @Consumes({ MediaType.WILDCARD })
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_DOMAIN_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response object(@PathParam("oid") final String oidStr, final InputStream object) {
-
-        init(RepresentationType.DOMAIN_OBJECT, Where.OBJECT_FORMS);
-
-        final String objectStr = DomainResourceHelper.asStringUtf8(object);
-        final JsonRepresentation objectRepr = DomainResourceHelper.readAsMap(objectStr);
-        if (!objectRepr.isMap()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Body is not a map; got %s", objectRepr);
-        }
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-
-        final JsonRepresentation propertiesList = objectRepr.getArrayEnsured("members[memberType=property]");
-        if (propertiesList == null) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Could not find properties list (no members[memberType=property]); got %s", objectRepr);
-        }
-
-        final IsisTransactionManager transactionManager = getResourceContext().getPersistenceSession().getTransactionManager();
-        transactionManager.startTransaction();
-        try {
-            if (!DomainResourceHelper.copyOverProperties(getResourceContext(), objectAdapter, propertiesList)) {
-                transactionManager.abortTransaction();
-                throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, objectRepr, "Illegal property value");
-            }
-
-            final Consent validity = objectAdapter.getSpecification().isValid(objectAdapter);
-            if (validity.isVetoed()) {
-                transactionManager.abortTransaction();
-                throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, objectRepr, validity.getReason());
-            }
-
-            transactionManager.endTransaction();
-        } finally {
-            // in case an exception got thrown somewhere...
-            if (!transactionManager.getTransaction().getState().isComplete()) {
-                transactionManager.abortTransaction();
-            }
-        }
-
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-        return helper.objectRepresentation();
-    }
-
-    // //////////////////////////////////////////////////////////
-    // domain object property
-    // //////////////////////////////////////////////////////////
-
-    @Override
-    @GET
-    @Path("/{oid}/properties/{propertyId}")
-    @Consumes({ MediaType.WILDCARD })
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response propertyDetails(@PathParam("oid") final String oidStr, @PathParam("propertyId") final String propertyId) {
-        init(RepresentationType.OBJECT_PROPERTY, Where.OBJECT_FORMS);
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-
-        return helper.propertyDetails(objectAdapter, propertyId, MemberMode.NOT_MUTATING, Caching.NONE, getResourceContext().getWhere());
-    }
-
-    @Override
-    @PUT
-    @Path("/{oid}/properties/{propertyId}")
-    @Consumes({ MediaType.WILDCARD })
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response modifyProperty(@PathParam("oid") final String oidStr, @PathParam("propertyId") final String propertyId, final InputStream body) {
-        init(Where.OBJECT_FORMS);
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-
-        final OneToOneAssociation property = helper.getPropertyThatIsVisibleAndUsable(propertyId, Intent.MUTATE, getResourceContext().getWhere());
-
-        final ObjectSpecification propertySpec = property.getSpecification();
-        final String bodyAsString = DomainResourceHelper.asStringUtf8(body);
-
-        final ObjectAdapter argAdapter = helper.parseAsMapWithSingleValue(propertySpec, bodyAsString);
-
-        final Consent consent = property.isAssociationValid(objectAdapter, argAdapter);
-        if (consent.isVetoed()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.UNAUTHORIZED, consent.getReason());
-        }
-
-        property.set(objectAdapter, argAdapter);
-
-        return helper.propertyDetails(objectAdapter, propertyId, MemberMode.MUTATING, Caching.NONE, getResourceContext().getWhere());
-    }
-
-    @Override
-    @DELETE
-    @Path("/{oid}/properties/{propertyId}")
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response clearProperty(@PathParam("oid") final String oidStr, @PathParam("propertyId") final String propertyId) {
-        init(Where.OBJECT_FORMS);
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-
-        final OneToOneAssociation property = helper.getPropertyThatIsVisibleAndUsable(propertyId, Intent.MUTATE, getResourceContext().getWhere());
-
-        final Consent consent = property.isAssociationValid(objectAdapter, null);
-        if (consent.isVetoed()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.UNAUTHORIZED, consent.getReason());
-        }
-
-        property.set(objectAdapter, null);
-
-        return helper.propertyDetails(objectAdapter, propertyId, MemberMode.MUTATING, Caching.NONE, getResourceContext().getWhere());
-    }
-
-    // //////////////////////////////////////////////////////////
-    // domain object collection
-    // //////////////////////////////////////////////////////////
-
-    @Override
-    @GET
-    @Path("/{oid}/collections/{collectionId}")
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response accessCollection(@PathParam("oid") final String oidStr, @PathParam("collectionId") final String collectionId) {
-        init(RepresentationType.OBJECT_COLLECTION, Where.PARENTED_TABLES);
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-
-        return helper.collectionDetails(objectAdapter, collectionId, MemberMode.NOT_MUTATING, Caching.NONE, getResourceContext().getWhere());
-    }
-
-    @Override
-    @PUT
-    @Path("/{oid}/collections/{collectionId}")
-    @Consumes({ MediaType.WILDCARD })
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response addToSet(@PathParam("oid") final String oidStr, @PathParam("collectionId") final String collectionId, final InputStream body) {
-        init(Where.PARENTED_TABLES);
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-
-        final OneToManyAssociation collection = helper.getCollectionThatIsVisibleAndUsable(collectionId, Intent.MUTATE, getResourceContext().getWhere());
-
-        if (!collection.getCollectionSemantics().isSet()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Collection '%s' does not have set semantics", collectionId);
-        }
-
-        final ObjectSpecification collectionSpec = collection.getSpecification();
-        final String bodyAsString = DomainResourceHelper.asStringUtf8(body);
-        final ObjectAdapter argAdapter = helper.parseAsMapWithSingleValue(collectionSpec, bodyAsString);
-
-        final Consent consent = collection.isValidToAdd(objectAdapter, argAdapter);
-        if (consent.isVetoed()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.UNAUTHORIZED, consent.getReason());
-        }
-
-        collection.addElement(objectAdapter, argAdapter);
-
-        return helper.collectionDetails(objectAdapter, collectionId, MemberMode.MUTATING, Caching.NONE, getResourceContext().getWhere());
-    }
-
-    @Override
-    @POST
-    @Path("/{oid}/collections/{collectionId}")
-    @Consumes({ MediaType.WILDCARD })
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response addToList(@PathParam("oid") final String oidStr, @PathParam("collectionId") final String collectionId, final InputStream body) {
-        init(Where.PARENTED_TABLES);
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-
-        final OneToManyAssociation collection = helper.getCollectionThatIsVisibleAndUsable(collectionId, Intent.MUTATE, getResourceContext().getWhere());
-
-        if (!collection.getCollectionSemantics().isListOrArray()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.METHOD_NOT_ALLOWED, "Collection '%s' does not have list or array semantics", collectionId);
-        }
-
-        final ObjectSpecification collectionSpec = collection.getSpecification();
-        final String bodyAsString = DomainResourceHelper.asStringUtf8(body);
-        final ObjectAdapter argAdapter = helper.parseAsMapWithSingleValue(collectionSpec, bodyAsString);
-
-        final Consent consent = collection.isValidToAdd(objectAdapter, argAdapter);
-        if (consent.isVetoed()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.UNAUTHORIZED, consent.getReason());
-        }
-
-        collection.addElement(objectAdapter, argAdapter);
-
-        return helper.collectionDetails(objectAdapter, collectionId, MemberMode.MUTATING, Caching.NONE, getResourceContext().getWhere());
-    }
-
-    @Override
-    @DELETE
-    @Path("/{oid}/collections/{collectionId}")
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response removeFromCollection(@PathParam("oid") final String oidStr, @PathParam("collectionId") final String collectionId) {
-        init(Where.PARENTED_TABLES);
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-
-        final OneToManyAssociation collection = helper.getCollectionThatIsVisibleAndUsable(collectionId, Intent.MUTATE, getResourceContext().getWhere());
-
-        final ObjectSpecification collectionSpec = collection.getSpecification();
-        final ObjectAdapter argAdapter = helper.parseAsMapWithSingleValue(collectionSpec, getResourceContext().getQueryString());
-
-        final Consent consent = collection.isValidToRemove(objectAdapter, argAdapter);
-        if (consent.isVetoed()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.UNAUTHORIZED, consent.getReason());
-        }
-
-        collection.removeElement(objectAdapter, argAdapter);
-
-        return helper.collectionDetails(objectAdapter, collectionId, MemberMode.MUTATING, Caching.NONE, getResourceContext().getWhere());
-    }
-
-    // //////////////////////////////////////////////////////////
-    // domain object action
-    // //////////////////////////////////////////////////////////
-
-    @Override
-    @GET
-    @Path("/{oid}/actions/{actionId}")
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response actionPrompt(@PathParam("oid") final String oidStr, @PathParam("actionId") final String actionId) {
-        init(RepresentationType.OBJECT_ACTION, Where.OBJECT_FORMS);
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-
-        return helper.actionPrompt(actionId, getResourceContext().getWhere());
-    }
-
-    // //////////////////////////////////////////////////////////
-    // domain object action invoke
-    // //////////////////////////////////////////////////////////
-
-    @Override
-    @GET
-    @Path("/{oid}/actions/{actionId}/invoke")
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response invokeActionQueryOnly(@PathParam("oid") final String oidStr, @PathParam("actionId") final String actionId) {
-        init(RepresentationType.ACTION_RESULT, Where.STANDALONE_TABLES);
-
-        final JsonRepresentation arguments = getResourceContext().getQueryStringAsJsonRepr();
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-
-        return helper.invokeActionQueryOnly(actionId, arguments, getResourceContext().getWhere());
-    }
-
-    @Override
-    @PUT
-    @Path("/{oid}/actions/{actionId}/invoke")
-    @Consumes({ MediaType.WILDCARD })
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response invokeActionIdempotent(@PathParam("oid") final String oidStr, @PathParam("actionId") final String actionId, final InputStream arguments) {
-        init(RepresentationType.ACTION_RESULT, Where.STANDALONE_TABLES);
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-
-        return helper.invokeActionIdempotent(actionId, arguments, getResourceContext().getWhere());
-    }
-
-    @Override
-    @POST
-    @Path("/{oid}/actions/{actionId}/invoke")
-    @Consumes({ MediaType.WILDCARD })
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response invokeAction(@PathParam("oid") final String oidStr, @PathParam("actionId") final String actionId, final InputStream body) {
-        init(RepresentationType.ACTION_RESULT, Where.STANDALONE_TABLES);
-
-        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), objectAdapter);
-
-        return helper.invokeAction(actionId, body, getResourceContext().getWhere());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainResourceHelper.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainResourceHelper.java b/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainResourceHelper.java
deleted file mode 100644
index fa1e187..0000000
--- a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainResourceHelper.java
+++ /dev/null
@@ -1,592 +0,0 @@
-
-/**
- *  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.viewer.resources.domainobjects;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.ResponseBuilder;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.Lists;
-import com.google.common.io.ByteStreams;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.map.JsonMappingException;
-
-import org.apache.isis.applib.annotation.ActionSemantics;
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.version.Version;
-import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
-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.core.metamodel.spec.feature.ObjectAssociation;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
-import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
-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.RestfulResponse.HttpStatusCode;
-import org.apache.isis.viewer.restfulobjects.applib.util.JsonMapper;
-import org.apache.isis.viewer.restfulobjects.applib.util.UrlEncodingUtils;
-import org.apache.isis.viewer.restfulobjects.viewer.RendererContext;
-import org.apache.isis.viewer.restfulobjects.viewer.ResourceContext;
-import org.apache.isis.viewer.restfulobjects.viewer.RestfulObjectsApplicationException;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.RendererFactory;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.RendererFactoryRegistry;
-import org.apache.isis.viewer.restfulobjects.viewer.resources.ResourceAbstract;
-import org.apache.isis.viewer.restfulobjects.viewer.resources.ResourceAbstract.Caching;
-import org.apache.isis.viewer.restfulobjects.viewer.resources.domainobjects.JsonValueEncoder.ExpectedStringRepresentingValueException;
-import org.apache.isis.viewer.restfulobjects.viewer.util.OidUtils;
-import org.apache.isis.viewer.restfulobjects.viewer.util.UrlDecoderUtils;
-import org.apache.isis.viewer.restfulobjects.viewer.util.UrlParserUtils;
-
-public final class DomainResourceHelper {
-
-    private static final DateFormat ETAG_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
-
-    private final RendererContext resourceContext;
-    private ObjectAdapterLinkTo adapterLinkTo;
-
-    private final ObjectAdapter objectAdapter;
-
-    public DomainResourceHelper(final RendererContext resourceContext, final ObjectAdapter objectAdapter) {
-        this.resourceContext = resourceContext;
-        this.objectAdapter = objectAdapter;
-        using(new DomainObjectLinkTo());
-    }
-
-    public DomainResourceHelper using(final ObjectAdapterLinkTo linkTo) {
-        adapterLinkTo = linkTo;
-        adapterLinkTo.usingUrlBase(resourceContext).with(objectAdapter);
-        return this;
-    }
-
-    // //////////////////////////////////////////////////////////////
-    // multiple properties (persist or multi-property update)
-    // //////////////////////////////////////////////////////////////
-
-    static boolean copyOverProperties(final RendererContext resourceContext, final ObjectAdapter objectAdapter, final JsonRepresentation propertiesList) {
-        final ObjectSpecification objectSpec = objectAdapter.getSpecification();
-        final List<ObjectAssociation> properties = objectSpec.getAssociations(ObjectAssociationFilters.PROPERTIES);
-        boolean allOk = true;
-
-        for (final ObjectAssociation association : properties) {
-            final OneToOneAssociation property = (OneToOneAssociation) association;
-            final ObjectSpecification propertySpec = property.getSpecification();
-            final String id = property.getId();
-            final JsonRepresentation propertyRepr = propertiesList.getRepresentation("[id=%s]", id);
-            if (propertyRepr == null) {
-                if (property.isMandatory()) {
-                    throw new IllegalArgumentException(String.format("Mandatory field %s missing", property.getName()));
-                }
-                continue;
-            }
-            final JsonRepresentation valueRepr = propertyRepr.getRepresentation("value");
-            final Consent usable = property.isUsable(resourceContext.getAuthenticationSession() , objectAdapter, resourceContext.getWhere());
-            if (usable.isVetoed()) {
-                propertyRepr.mapPut("invalidReason", usable.getReason());
-                allOk = false;
-                continue;
-            }
-            final ObjectAdapter valueAdapter = objectAdapterFor(resourceContext, propertySpec, valueRepr);
-            final Consent consent = property.isAssociationValid(objectAdapter, valueAdapter);
-            if (consent.isAllowed()) {
-                try {
-                    property.set(objectAdapter, valueAdapter);
-                } catch (final IllegalArgumentException ex) {
-                    propertyRepr.mapPut("invalidReason", ex.getMessage());
-                    allOk = false;
-                }
-            } else {
-                propertyRepr.mapPut("invalidReason", consent.getReason());
-                allOk = false;
-            }
-        }
-
-        return allOk;
-    }
-
-    // //////////////////////////////////////////////////////////////
-    // propertyDetails
-    // //////////////////////////////////////////////////////////////
-
-    public Response objectRepresentation() {
-        final RendererFactory rendererFactory = getRendererFactoryRegistry().find(RepresentationType.DOMAIN_OBJECT);
-
-        final DomainObjectReprRenderer renderer = (DomainObjectReprRenderer) rendererFactory.newRenderer(resourceContext, null, JsonRepresentation.newMap());
-        renderer.with(objectAdapter).includesSelf();
-
-        final ResponseBuilder respBuilder = ResourceAbstract.responseOfOk(renderer, Caching.NONE);
-
-        final Version version = objectAdapter.getVersion();
-        if (version != null && version.getTime() != null) {
-            respBuilder.tag(ETAG_FORMAT.format(version.getTime()));
-        }
-        return respBuilder.build();
-    }
-
-    // //////////////////////////////////////////////////////////////
-    // propertyDetails
-    // //////////////////////////////////////////////////////////////
-
-    public enum MemberMode {
-        NOT_MUTATING {
-            @Override
-            public void apply(final AbstractObjectMemberReprRenderer<?, ?> renderer) {
-                renderer.asStandalone();
-            }
-        },
-        MUTATING {
-            @Override
-            public void apply(final AbstractObjectMemberReprRenderer<?, ?> renderer) {
-                renderer.asMutated();
-            }
-        };
-
-        public abstract void apply(AbstractObjectMemberReprRenderer<?, ?> renderer);
-    }
-
-    Response propertyDetails(final ObjectAdapter objectAdapter, final String propertyId, final MemberMode memberMode, final Caching caching, Where where) {
-
-        final OneToOneAssociation property = getPropertyThatIsVisibleAndUsable(propertyId, Intent.ACCESS, where);
-
-        final RendererFactory factory = getRendererFactoryRegistry().find(RepresentationType.OBJECT_PROPERTY);
-        final ObjectPropertyReprRenderer renderer = (ObjectPropertyReprRenderer) factory.newRenderer(resourceContext, null, JsonRepresentation.newMap());
-
-        renderer.with(new ObjectAndProperty(objectAdapter, property)).usingLinkTo(adapterLinkTo);
-
-        memberMode.apply(renderer);
-
-        return ResourceAbstract.responseOfOk(renderer, caching).build();
-    }
-
-    // //////////////////////////////////////////////////////////////
-    // collectionDetails
-    // //////////////////////////////////////////////////////////////
-
-    Response collectionDetails(final ObjectAdapter objectAdapter, final String collectionId, final MemberMode memberMode, final Caching caching, Where where) {
-
-        final OneToManyAssociation collection = getCollectionThatIsVisibleAndUsable(collectionId, Intent.ACCESS, where);
-
-        final RendererFactory factory = RendererFactoryRegistry.instance.find(RepresentationType.OBJECT_COLLECTION);
-        final ObjectCollectionReprRenderer renderer = (ObjectCollectionReprRenderer) factory.newRenderer(resourceContext, null, JsonRepresentation.newMap());
-
-        renderer.with(new ObjectAndCollection(objectAdapter, collection)).usingLinkTo(adapterLinkTo);
-
-        memberMode.apply(renderer);
-
-        return ResourceAbstract.responseOfOk(renderer, caching).build();
-    }
-
-    // //////////////////////////////////////////////////////////////
-    // action Prompt
-    // //////////////////////////////////////////////////////////////
-
-    Response actionPrompt(final String actionId, Where where) {
-        final ObjectAction action = getObjectActionThatIsVisibleAndUsable(actionId, Intent.ACCESS, where);
-
-        final RendererFactory factory = getRendererFactoryRegistry().find(RepresentationType.OBJECT_ACTION);
-        final ObjectActionReprRenderer renderer = (ObjectActionReprRenderer) factory.newRenderer(resourceContext, null, JsonRepresentation.newMap());
-
-        renderer.with(new ObjectAndAction(objectAdapter, action)).usingLinkTo(adapterLinkTo).asStandalone();
-
-        return ResourceAbstract.responseOfOk(renderer, Caching.NONE).build();
-    }
-
-    // //////////////////////////////////////////////////////////////
-    // invoke action
-    // //////////////////////////////////////////////////////////////
-
-    enum Intent {
-        ACCESS, MUTATE;
-
-        public boolean isMutate() {
-            return this == MUTATE;
-        }
-    }
-
-    Response invokeActionQueryOnly(final String actionId, final JsonRepresentation arguments, Where where) {
-        final ObjectAction action = getObjectActionThatIsVisibleAndUsable(actionId, Intent.ACCESS, where);
-
-        final ActionSemantics.Of actionSemantics = action.getSemantics();
-        if (actionSemantics != ActionSemantics.Of.SAFE) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.METHOD_NOT_ALLOWED, "Method not allowed; action '%s' is not query only", action.getId());
-        }
-
-        return invokeActionUsingAdapters(action, arguments);
-    }
-
-    Response invokeActionIdempotent(final String actionId, final InputStream body, Where where) {
-
-        final ObjectAction action = getObjectActionThatIsVisibleAndUsable(actionId, Intent.MUTATE, where);
-
-        final ActionSemantics.Of actionSemantics = action.getSemantics();
-        if (!actionSemantics.isIdempotentInNature()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.METHOD_NOT_ALLOWED, "Method not allowed; action '%s' is not idempotent", action.getId());
-        }
-        final String bodyAsString = asStringUtf8(body);
-        final JsonRepresentation arguments = readAsMap(bodyAsString);
-
-        return invokeActionUsingAdapters(action, arguments);
-    }
-
-    Response invokeAction(final String actionId, final InputStream body, Where where) {
-        final ObjectAction action = getObjectActionThatIsVisibleAndUsable(actionId, Intent.MUTATE, where);
-
-        final String bodyAsString = asStringUtf8(body);
-        final JsonRepresentation arguments = readAsMap(bodyAsString);
-
-        return invokeActionUsingAdapters(action, arguments);
-    }
-
-    Response invokeActionUsingAdapters(final ObjectAction action, final JsonRepresentation arguments) {
-
-        final List<ObjectAdapter> argAdapters = parseArguments(action, arguments);
-
-        // validate individual args
-        final List<ObjectActionParameter> parameters = action.getParameters();
-        for (int i = 0; i < parameters.size(); i++) {
-            final ObjectActionParameter parameter = parameters.get(i);
-            final ObjectAdapter argAdapter = argAdapters.get(i);
-            if (argAdapter == null) {
-                // can only happen if this is an optional parameter; nothing to
-                // do
-                continue;
-            }
-            if (argAdapter.getSpecification().containsFacet(ValueFacet.class)) {
-                final Object arg = argAdapter.getObject();
-                final String reasonNotValid = parameter.isValid(objectAdapter, arg, null);
-                if (reasonNotValid != null) {
-                    throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_ACCEPTABLE, reasonNotValid);
-                }
-            }
-        }
-
-        // validate all args
-        final ObjectAdapter[] argArray = argAdapters.toArray(new ObjectAdapter[0]);
-        final Consent consent = action.isProposedArgumentSetValid(objectAdapter, argArray);
-        if (consent.isVetoed()) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_ACCEPTABLE, consent.getReason());
-        }
-
-        // invoke
-        final ObjectAdapter returnedAdapter = action.execute(objectAdapter, argArray);
-
-        // response (void)
-        final RendererFactory factory = getRendererFactoryRegistry().find(RepresentationType.ACTION_RESULT);
-        final ActionResultReprRenderer renderer = (ActionResultReprRenderer) factory.newRenderer(resourceContext, null, JsonRepresentation.newMap());
-
-        renderer.with(new ObjectAndActionInvocation(objectAdapter, action, arguments, returnedAdapter)).using(adapterLinkTo);
-
-        final ResponseBuilder respBuilder = ResourceAbstract.responseOfOk(renderer, Caching.NONE);
-
-        final Version version = objectAdapter.getVersion();
-        ResourceAbstract.addLastModifiedAndETagIfAvailable(respBuilder, version);
-
-        return respBuilder.build();
-    }
-
-    /**
-     *
-     * @param resourceContext
-     * @param objectSpec
-     *            - the {@link ObjectSpecification} to interpret the object as.
-     * @param node
-     *            - expected to be either a String or a Map (ie from within a
-     *            List, built by parsing a JSON structure).
-     */
-    private static ObjectAdapter objectAdapterFor(final RendererContext resourceContext, final ObjectSpecification objectSpec, final JsonRepresentation representation) {
-
-        if (representation == null) {
-            return null;
-        }
-
-        // value (encodable)
-        if (objectSpec.isEncodeable()) {
-            return new JsonValueEncoder().asAdapter(objectSpec, representation);
-        }
-
-        // reference
-        if (!representation.isLink()) {
-            throw new ExpectedMapRepresentingLinkException();
-        }
-        final JsonRepresentation argLink = representation.asLink();
-        final String oidFromHref = UrlParserUtils.oidFromLink(argLink);
-        if (oidFromHref == null) {
-            throw new ExpectedMapRepresentingLinkException();
-        }
-
-        final ObjectAdapter objectAdapter = OidUtils.getObjectAdapter(resourceContext, oidFromHref);
-        if (objectAdapter == null) {
-            throw new UnknownOidException(oidFromHref);
-        }
-        return objectAdapter;
-    }
-
-    /**
-     * Similar to
-     * {@link #objectAdapterFor(ResourceContext, ObjectSpecification, Object)},
-     * however the object being interpreted is a String holding URL encoded JSON
-     * (rather than having already been parsed into a Map representation).
-     *
-     * @throws IOException
-     * @throws JsonMappingException
-     * @throws JsonParseException
-     */
-    ObjectAdapter objectAdapterFor(final ObjectSpecification spec, final String urlEncodedJson) throws JsonParseException, JsonMappingException, IOException {
-
-        final String json = UrlDecoderUtils.urlDecode(urlEncodedJson);
-        final JsonRepresentation representation = JsonMapper.instance().read(json);
-        return objectAdapterFor(resourceContext, spec, representation);
-    }
-
-    private static class ExpectedMapRepresentingLinkException extends IllegalArgumentException {
-        private static final long serialVersionUID = 1L;
-    }
-
-    private static class UnknownOidException extends IllegalArgumentException {
-        private static final long serialVersionUID = 1L;
-
-        public UnknownOidException(final String oid) {
-            super(UrlDecoderUtils.urlDecode(oid));
-        }
-    }
-
-    // ///////////////////////////////////////////////////////////////////
-    // get{MemberType}ThatIsVisibleAndUsable
-    // ///////////////////////////////////////////////////////////////////
-
-    protected OneToOneAssociation getPropertyThatIsVisibleAndUsable(final String propertyId, final Intent intent, Where where) {
-
-        final ObjectAssociation association = objectAdapter.getSpecification().getAssociation(propertyId);
-        if (association == null || !association.isOneToOneAssociation()) {
-            throwNotFoundException(propertyId, MemberType.PROPERTY);
-        }
-        final OneToOneAssociation property = (OneToOneAssociation) association;
-        return memberThatIsVisibleAndUsable(property, MemberType.PROPERTY, intent, where);
-    }
-
-    protected OneToManyAssociation getCollectionThatIsVisibleAndUsable(final String collectionId, final Intent intent, Where where) {
-
-        final ObjectAssociation association = objectAdapter.getSpecification().getAssociation(collectionId);
-        if (association == null || !association.isOneToManyAssociation()) {
-            throwNotFoundException(collectionId, MemberType.COLLECTION);
-        }
-        final OneToManyAssociation collection = (OneToManyAssociation) association;
-        return memberThatIsVisibleAndUsable(collection, MemberType.COLLECTION, intent, where);
-    }
-
-    protected ObjectAction getObjectActionThatIsVisibleAndUsable(final String actionId, final Intent intent, Where where) {
-
-        final ObjectAction action = objectAdapter.getSpecification().getObjectAction(actionId);
-        if (action == null) {
-            throwNotFoundException(actionId, MemberType.ACTION);
-        }
-
-        return memberThatIsVisibleAndUsable(action, MemberType.ACTION, intent, where);
-    }
-
-    protected <T extends ObjectMember> T memberThatIsVisibleAndUsable(final T objectMember, final MemberType memberType, final Intent intent, Where where) {
-        final String memberId = objectMember.getId();
-        final AuthenticationSession authenticationSession = resourceContext.getAuthenticationSession();
-        if (objectMember.isVisible(authenticationSession, objectAdapter, where).isVetoed()) {
-            throwNotFoundException(memberId, memberType);
-        }
-        if (intent.isMutate()) {
-            final Consent usable = objectMember.isUsable(authenticationSession, objectAdapter, where);
-            if (usable.isVetoed()) {
-                final String memberTypeStr = memberType.name().toLowerCase();
-                throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_ACCEPTABLE, "%s is not usable: '%s' (%s)", memberTypeStr, memberId, usable.getReason());
-            }
-        }
-        return objectMember;
-    }
-
-    protected static void throwNotFoundException(final String memberId, final MemberType memberType) {
-        final String memberTypeStr = memberType.name().toLowerCase();
-        throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND, "%s '%s' either does not exist or is not visible", memberTypeStr, memberId);
-    }
-
-    // ///////////////////////////////////////////////////////////////////
-    // parseBody
-    // ///////////////////////////////////////////////////////////////////
-
-    /**
-     *
-     * @param objectSpec
-     * @param bodyAsString
-     *            - as per {@link #asStringUtf8(InputStream)}
-     * @return
-     */
-    ObjectAdapter parseAsMapWithSingleValue(final ObjectSpecification objectSpec, final String bodyAsString) {
-        final JsonRepresentation arguments = readAsMap(bodyAsString);
-
-        return parseAsMapWithSingleValue(objectSpec, arguments);
-    }
-
-    ObjectAdapter parseAsMapWithSingleValue(final ObjectSpecification objectSpec, final JsonRepresentation arguments) {
-        final JsonRepresentation representation = arguments.getRepresentation("value");
-        if (arguments.size() != 1 || representation == null) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Body should be a map with a single key 'value' whose value represents an instance of type '%s'", resourceFor(objectSpec));
-        }
-
-        return objectAdapterFor(resourceContext, objectSpec, representation);
-    }
-
-    private List<ObjectAdapter> parseArguments(final ObjectAction action, final JsonRepresentation arguments) {
-        return parseArguments(resourceContext, action, arguments);
-    }
-
-    public static List<ObjectAdapter> parseArguments(final RendererContext resourceContext, final ObjectAction action, final JsonRepresentation arguments) {
-        final List<JsonRepresentation> argList = argListFor(action, arguments);
-
-        final List<ObjectAdapter> argAdapters = Lists.newArrayList();
-        final List<ObjectActionParameter> parameters = action.getParameters();
-        for (int i = 0; i < argList.size(); i++) {
-            final String paramName = parameters.get(i).getName();
-            final JsonRepresentation arg = argList.get(i);
-            final ObjectSpecification paramSpec = parameters.get(i).getSpecification();
-            try {
-                final ObjectAdapter objectAdapter = objectAdapterFor(resourceContext, paramSpec, arg);
-                argAdapters.add(objectAdapter);
-            } catch (final ExpectedStringRepresentingValueException e) {
-                throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Action '%s', argument %s should be a URL encoded string representing a value of type %s", action.getId(), paramName, resourceFor(paramSpec));
-            } catch (final ExpectedMapRepresentingLinkException e) {
-                throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Action '%s', argument %s should be a map representing a link to reference of type %s", action.getId(), paramName, resourceFor(paramSpec));
-            }
-        }
-        return argAdapters;
-    }
-
-    private static List<JsonRepresentation> argListFor(final ObjectAction action, final JsonRepresentation arguments) {
-        final List<JsonRepresentation> argList = Lists.newArrayList();
-
-        // ensure that we have no arguments that are not parameters
-        for (final Entry<String, JsonRepresentation> arg : arguments.mapIterable()) {
-            final String argName = arg.getKey();
-            if (action.getParameterById(argName) == null) {
-                throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Action '%s' does not have a parameter %s but an argument of that name was provided", action.getId(), argName);
-            }
-        }
-
-        // ensure that an argument value has been provided for all non-optional
-        // parameters
-        final List<ObjectActionParameter> parameters = action.getParameters();
-        for (final ObjectActionParameter param : parameters) {
-            final String paramId = param.getId();
-            final JsonRepresentation argRepr = arguments.getRepresentation(paramId);
-            if (argRepr == null && !param.isOptional()) {
-                throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "Action '%s', no argument found for (mandatory) parameter '%s'", action.getId(), paramId);
-            }
-            argList.add(argRepr);
-        }
-        return argList;
-    }
-
-    public static JsonRepresentation readParameterMapAsMap(final Map<String, String[]> parameterMap) {
-        final JsonRepresentation map = JsonRepresentation.newMap();
-        for (final Map.Entry<String, String[]> parameter : parameterMap.entrySet()) {
-            map.mapPut(parameter.getKey(), parameter.getValue()[0]);
-        }
-        return map;
-    }
-
-    public static JsonRepresentation readQueryStringAsMap(final String queryString) {
-        if (queryString == null) {
-            return JsonRepresentation.newMap();
-        }
-        final String queryStringTrimmed = queryString.trim();
-        if (queryStringTrimmed.isEmpty()) {
-            return JsonRepresentation.newMap();
-        }
-        final String queryStringUrlDecoded = UrlEncodingUtils.urlDecode(queryStringTrimmed);
-        if (queryStringUrlDecoded.isEmpty()) {
-            return JsonRepresentation.newMap();
-        }
-
-        return read(queryStringUrlDecoded, "query string");
-    }
-
-    public static JsonRepresentation readAsMap(final String body) {
-        if (body == null) {
-            return JsonRepresentation.newMap();
-        }
-        final String bodyTrimmed = body.trim();
-        if (bodyTrimmed.isEmpty()) {
-            return JsonRepresentation.newMap();
-        }
-        return read(bodyTrimmed, "body");
-    }
-
-    private static JsonRepresentation read(final String args, final String argsNature) {
-        try {
-            final JsonRepresentation jsonRepr = JsonMapper.instance().read(args);
-            if (!jsonRepr.isMap()) {
-                throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, "could not read %s as a JSON map", argsNature);
-            }
-            return jsonRepr;
-        } catch (final JsonParseException e) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, e, "could not parse %s", argsNature);
-        } catch (final JsonMappingException e) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, e, "could not read %s as JSON", argsNature);
-        } catch (final IOException e) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, e, "could not parse %s", argsNature);
-        }
-    }
-
-    public static String asStringUtf8(final InputStream body) {
-        try {
-            final byte[] byteArray = ByteStreams.toByteArray(body);
-            return new String(byteArray, Charsets.UTF_8);
-        } catch (final IOException e) {
-            throw RestfulObjectsApplicationException.create(HttpStatusCode.BAD_REQUEST, e, "could not read body");
-        }
-    }
-
-    // //////////////////////////////////////////////////////////////
-    // misc
-    // //////////////////////////////////////////////////////////////
-
-    private static String resourceFor(final ObjectSpecification objectSpec) {
-        // TODO: should return a string in the form
-        // http://localhost:8080/types/xxx
-        return objectSpec.getFullIdentifier();
-    }
-
-    // //////////////////////////////////////////////////////////////
-    // dependencies
-    // //////////////////////////////////////////////////////////////
-
-    protected RendererFactoryRegistry getRendererFactoryRegistry() {
-        // TODO: yuck
-        return RendererFactoryRegistry.instance;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainServiceLinkTo.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainServiceLinkTo.java b/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainServiceLinkTo.java
deleted file mode 100644
index 3ad69dc..0000000
--- a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainServiceLinkTo.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- *  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.viewer.resources.domainobjects;
-
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.services.ServiceUtil;
-import org.apache.isis.viewer.restfulobjects.applib.links.Rel;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.LinkBuilder;
-
-public class DomainServiceLinkTo extends DomainObjectLinkTo {
-    private String serviceId;
-
-    @Override
-    public ObjectAdapterLinkTo with(final ObjectAdapter objectAdapter) {
-        serviceId = ServiceUtil.id(objectAdapter.getObject());
-        return super.with(objectAdapter);
-    }
-
-    @Override
-    protected String linkRef() {
-        final StringBuilder buf = new StringBuilder("services/");
-        buf.append(serviceId);
-        return buf.toString();
-    }
-
-    @Override
-    protected Rel defaultRel() {
-        return Rel.SERVICE;
-    }
-
-    @Override
-    public LinkBuilder builder(final Rel rel) {
-        return super.builder(rel).withId(serviceId);
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/bb79d33e/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainServiceResourceServerside.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainServiceResourceServerside.java b/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainServiceResourceServerside.java
deleted file mode 100644
index 9d68fb2..0000000
--- a/component/viewer/restfulobjects/impl/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/domainobjects/DomainServiceResourceServerside.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- *  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.viewer.resources.domainobjects;
-
-import java.io.InputStream;
-import java.util.List;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
-import org.apache.isis.viewer.restfulobjects.domainobjects.DomainServiceResource;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.RendererFactory;
-import org.apache.isis.viewer.restfulobjects.viewer.representations.RendererFactoryRegistry;
-import org.apache.isis.viewer.restfulobjects.viewer.resources.ResourceAbstract;
-import org.apache.isis.viewer.restfulobjects.viewer.resources.domainobjects.DomainResourceHelper.MemberMode;
-
-@Path("/services")
-public class DomainServiceResourceServerside extends ResourceAbstract implements DomainServiceResource {
-
-    @Override
-    @GET
-    @Path("/")
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_LIST, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response services() {
-        final RepresentationType representationType = RepresentationType.LIST;
-        init(representationType, Where.STANDALONE_TABLES);
-
-        final List<ObjectAdapter> serviceAdapters = getResourceContext().getServiceAdapters();
-
-        final RendererFactory factory = RendererFactoryRegistry.instance.find(representationType);
-
-        final ListReprRenderer renderer = (ListReprRenderer) factory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
-        renderer.usingLinkToBuilder(new DomainServiceLinkTo()).withSelf("services").with(serviceAdapters);
-
-        return responseOfOk(renderer, Caching.ONE_DAY).build();
-    }
-
-    // //////////////////////////////////////////////////////////
-    // domain service
-    // //////////////////////////////////////////////////////////
-
-    @Override
-    @GET
-    @Path("/{serviceId}")
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_DOMAIN_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response service(@PathParam("serviceId") final String serviceId) {
-        init(RepresentationType.DOMAIN_OBJECT, Where.OBJECT_FORMS);
-
-        final ObjectAdapter serviceAdapter = getServiceAdapter(serviceId);
-
-        final RendererFactory rendererFactory = rendererFactoryRegistry.find(RepresentationType.DOMAIN_OBJECT);
-
-        final DomainObjectReprRenderer renderer = (DomainObjectReprRenderer) rendererFactory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
-        renderer.usingLinkToBuilder(new DomainServiceLinkTo()).with(serviceAdapter).includesSelf();
-
-        return responseOfOk(renderer, Caching.ONE_DAY).build();
-    }
-
-    // //////////////////////////////////////////////////////////
-    // domain service property
-    // //////////////////////////////////////////////////////////
-
-    @Override
-    @GET
-    @Path("/{serviceId}/properties/{propertyId}")
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response propertyDetails(@PathParam("serviceId") final String serviceId, @PathParam("propertyId") final String propertyId) {
-        init(RepresentationType.OBJECT_PROPERTY, Where.OBJECT_FORMS);
-
-        final ObjectAdapter serviceAdapter = getServiceAdapter(serviceId);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), serviceAdapter).using(new DomainServiceLinkTo());
-
-        return helper.propertyDetails(serviceAdapter, propertyId, MemberMode.NOT_MUTATING, Caching.ONE_DAY, getResourceContext().getWhere());
-    }
-
-    // //////////////////////////////////////////////////////////
-    // domain service action
-    // //////////////////////////////////////////////////////////
-
-    @Override
-    @GET
-    @Path("/{serviceId}/actions/{actionId}")
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response actionPrompt(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId) {
-        init(RepresentationType.OBJECT_ACTION, Where.OBJECT_FORMS);
-
-        final ObjectAdapter serviceAdapter = getServiceAdapter(serviceId);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), serviceAdapter).using(new DomainServiceLinkTo());
-
-        return helper.actionPrompt(actionId, getResourceContext().getWhere());
-    }
-
-    // //////////////////////////////////////////////////////////
-    // domain service action invoke
-    // //////////////////////////////////////////////////////////
-
-    @Override
-    @GET
-    @Path("/{serviceId}/actions/{actionId}/invoke")
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response invokeActionQueryOnly(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId) {
-        init(RepresentationType.ACTION_RESULT, Where.STANDALONE_TABLES);
-
-        final JsonRepresentation arguments = getResourceContext().getQueryStringAsJsonRepr();
-
-        final ObjectAdapter serviceAdapter = getServiceAdapter(serviceId);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), serviceAdapter).using(new DomainServiceLinkTo());
-
-        return helper.invokeActionQueryOnly(actionId, arguments, getResourceContext().getWhere());
-    }
-
-    @Override
-    @PUT
-    @Path("/{serviceId}/actions/{actionId}/invoke")
-    @Consumes({ MediaType.WILDCARD })
-    // to save the client having to specify a Content-Type: application/json
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response invokeActionIdempotent(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId, final InputStream arguments) {
-        init(RepresentationType.ACTION_RESULT, Where.STANDALONE_TABLES);
-
-        final ObjectAdapter serviceAdapter = getServiceAdapter(serviceId);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), serviceAdapter).using(new DomainServiceLinkTo());
-
-        return helper.invokeActionIdempotent(actionId, arguments, getResourceContext().getWhere());
-    }
-
-    @Override
-    @POST
-    @Path("/{serviceId}/actions/{actionId}/invoke")
-    @Consumes({ MediaType.WILDCARD })
-    // to save the client having to specify a Content-Type: application/json
-    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response invokeAction(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId, final InputStream arguments) {
-        init(RepresentationType.ACTION_RESULT, Where.STANDALONE_TABLES);
-
-        final ObjectAdapter serviceAdapter = getServiceAdapter(serviceId);
-        final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), serviceAdapter).using(new DomainServiceLinkTo());
-
-        return helper.invokeAction(actionId, arguments, getResourceContext().getWhere());
-    }
-
-}