content: /*
   *  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.causeway.viewer.restfulobjects.applib.domainobjects;
  
  import java.util.Map;
  import java.util.function.Predicate;
  import java.util.stream.Collectors;
  
  import com.fasterxml.jackson.databind.JsonNode;
  
  import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
  import org.apache.causeway.viewer.restfulobjects.applib.LinkRepresentation;
  import org.apache.causeway.viewer.restfulobjects.applib.Rel;
  
  /**
   * @since 1.x {@index}
   */
  public class DomainObjectRepresentation extends DomainRepresentation  {
  
      public DomainObjectRepresentation(final JsonNode jsonNode) {
          super(jsonNode);
      }
  
      public String getTitle() {
          return getString("title");
      }
  
      /**
       * Populated only for domain objects, not for domain services.
       */
      public String getDomainType() {
          return getString("domainType");
      }
  
      /**
       * Populated only for domain objects, not for domain services.
       */
      public String getInstanceId() {
          return getString("instanceId");
      }
  
      /**
       * Populated only for domain services, not for domain objects.
       */
      public String getServiceId() {
          return getString("serviceId");
      }
  
      public JsonRepresentation getMembers() {
          return getRepresentation("members");
      }
  
      public DomainObjectMemberRepresentation getProperty(final String id) {
          return getMember(id, "property");
      }
  
      public JsonRepresentation getProperties() {
          return getMembersOfType("property");
      }
  
      public DomainObjectMemberRepresentation getCollection(final String id) {
          return getMember(id, "collection");
      }
  
      public JsonRepresentation getCollections() {
          return getMembersOfType("collection");
      }
  
      public DomainObjectMemberRepresentation getAction(final String id) {
          return getMember(id, "action");
      }
  
      public JsonRepresentation getActions() {
          return getMembersOfType("action");
      }
  
      /**
       * Only for transient, persistable, objects
       */
      public LinkRepresentation getPersistLink() {
          return getLinkWithRel(Rel.PERSIST);
      }
  
      /**
       * Causeway extension.
       */
      public String getOid() {
          return getString("extensions.oid");
      }
  
      private DomainObjectMemberRepresentation getMember(final String id, String memberType) {
          // TODO: would be nice to use "members.%s[memberType=...]" instead
          JsonRepresentation jsonRepr = getRepresentation("members.%s", id);
          if(jsonRepr == null) {
              return null;
          }
          DomainObjectMemberRepresentation member = jsonRepr.as(DomainObjectMemberRepresentation.class);
          return member.getMemberType().equals(memberType) ? member : null;
      }
  
      private JsonRepresentation getMembersOfType(String memberTypeOf) {
          final JsonRepresentation members = getRepresentation("members");
          return JsonRepresentation.newMap().mapPutEntries(
                  members.streamMapEntries()
                  .filter(havingMemberTypeOf(memberTypeOf))
                  .collect(Collectors.toList()) );
      }
  
      private static Predicate<Map.Entry<String, JsonRepresentation>> havingMemberTypeOf(final String memberTypeOf) {
          return new Predicate<Map.Entry<String, JsonRepresentation>>() {
              @Override
              public boolean test(Map.Entry<String, JsonRepresentation> input) {
                  final JsonRepresentation value = input.getValue();
                  final String memberType = value.getRepresentation("memberType").asString();
                  return memberTypeOf.equals(memberType);
              }
          };
      }
  
  }
  