All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.contentful.java.cda.ResourceUtils Maven / Gradle / Ivy

package com.contentful.java.cda;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import io.reactivex.Flowable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Predicate;
import retrofit2.Response;

import static com.contentful.java.cda.CDAType.ASSET;
import static com.contentful.java.cda.CDAType.DELETEDASSET;
import static com.contentful.java.cda.CDAType.DELETEDENTRY;
import static com.contentful.java.cda.CDAType.ENTRY;
import static com.contentful.java.cda.Constants.LOCALE;
import static com.contentful.java.cda.Util.extractNested;
import static com.contentful.java.cda.Util.queryParam;

final class ResourceUtils {
  private ResourceUtils() {
    throw new AssertionError();
  }

  static SynchronizedSpace iterate(Response spaceResponse, CDAClient client) {
    SynchronizedSpace space = ResourceFactory.fromResponse(spaceResponse);
    List items = space.items;
    while (true) {
      SynchronizedSpace nextSpace = nextSpace(space, client);
      if (nextSpace == null) {
        break;
      }
      items.addAll(nextSpace.items());
      space = nextSpace;
    }
    space.items = items;
    localizeResources(space.items(), client.cache.space());
    return space;
  }

  static SynchronizedSpace nextSpace(SynchronizedSpace space, CDAClient client) {
    String nextPageUrl = space.nextPageUrl();
    if (nextPageUrl == null) {
      return null;
    }

    Response synchronizedSpace =
        client.service.sync(client.spaceId, null, queryParam(nextPageUrl, "sync_token"))
            .blockingFirst();

    return synchronizedSpace.body();
  }

  static void resolveLinks(ArrayResource array, CDAClient client) {
    for (CDAEntry entry : array.entries().values()) {
      ensureContentType(entry, client);
      for (CDAField field : entry.contentType().fields()) {
        if (field.linkType() != null) {
          resolveSingleLink(entry, field, array);
        } else if ("Array".equals(field.type) && "Link".equals(field.items().get("type"))) {
          resolveArrayOfLinks(entry, field, array);
        }
      }
    }
  }

  static void ensureContentType(CDAEntry entry, CDAClient client) {
    CDAContentType contentType = entry.contentType();
    if (contentType != null) {
      return;
    }

    String contentTypeId = extractNested(entry.attrs(), "contentType", "sys", "id");
    try {
      contentType = client.cacheTypeWithId(contentTypeId).blockingFirst();
    } catch (CDAResourceNotFoundException e) {
      throw new CDAContentTypeNotFoundException(entry.id(), CDAEntry.class, contentTypeId, e);
    }

    entry.setContentType(contentType);
  }

  @SuppressWarnings("unchecked")
  static void resolveArrayOfLinks(CDAEntry entry, CDAField field, ArrayResource array) {
    CDAType linkType =
        CDAType.valueOf(((String) field.items().get("linkType")).toUpperCase(LOCALE));
    Map value = (Map) entry.fields.get(field.id());
    if (value == null) {
      return;
    }
    for (String locale : value.keySet()) {
      List links = (List) value.get(locale);
      if (links == null) {
        continue;
      }
      List resolved = new ArrayList();
      for (int i = 0; i < links.size(); i++) {
        String linkId = getLinkId(links.get(i));
        if (linkId == null) {
          continue;
        }
        CDAResource resource = findLinkedResource(array, linkType, linkId);
        if (resource != null) {
          resolved.add(resource);
        }
      }
      value.put(locale, resolved);
    }
  }

  @SuppressWarnings("unchecked")
  static void resolveSingleLink(CDAEntry entry, CDAField field, ArrayResource array) {
    CDAType linkType = CDAType.valueOf(field.linkType().toUpperCase(LOCALE));
    Map value = (Map) entry.fields.get(field.id());
    if (value == null) {
      return;
    }
    Set toRemove = new HashSet();
    for (String locale : value.keySet()) {
      String linkId = getLinkId(value.get(locale));
      if (linkId == null) {
        continue;
      }
      CDAResource resource = findLinkedResource(array, linkType, linkId);
      if (resource == null) {
        toRemove.add(locale);
      } else {
        value.put(locale, resource);
      }
    }
    for (String locale : toRemove) {
      value.remove(locale);
    }
  }

  static String getLinkId(Object link) {
    if (link == null) {
      return null;
    }
    if (link instanceof CDAResource) {
      // already resolved
      return ((CDAResource) link).id();
    }
    return extractNested((Map) link, "sys", "id");
  }

  static CDAResource findLinkedResource(ArrayResource array, CDAType linkType,
                                        String id) {
    if (ASSET.equals(linkType)) {
      return array.assets().get(id);
    } else if (ENTRY.equals(linkType)) {
      return array.entries().get(id);
    }
    return null;
  }

  static void mapResources(Collection resources,
                           Map assets, Map entries) {
    for (CDAResource resource : resources) {
      CDAType type = resource.type();
      String id = resource.id();
      if (ASSET.equals(type)) {
        assets.put(id, (CDAAsset) resource);
      } else if (DELETEDASSET.equals(type)) {
        assets.remove(id);
      } else if (DELETEDENTRY.equals(type)) {
        entries.remove(id);
      } else if (ENTRY.equals(type)) {
        entries.put(id, (CDAEntry) resource);
      }
    }
  }

  static void mapDeletedResources(SynchronizedSpace space) {
    final Set assets;
    if (space.deletedAssets == null) {
      assets = new HashSet();
    } else {
      assets = new HashSet(space.deletedAssets);
    }

    final Set entries;
    if (space.deletedEntries == null) {
      entries = new HashSet();
    } else {
      entries = new HashSet(space.deletedEntries);
    }

    Flowable.fromIterable(space.items())
        .filter(new Predicate() {
          @Override public boolean test(CDAResource resource) {
            CDAType type = resource.type();
            return DELETEDASSET.equals(type) || DELETEDENTRY.equals(type);
          }
        })
        .subscribe(new Consumer() {
          @Override public void accept(CDAResource resource) {
            if (DELETEDASSET.equals(resource.type())) {
              assets.add(resource.id());
            } else {
              entries.add(resource.id());
            }
          }
        });
    space.deletedAssets = assets;
    space.deletedEntries = entries;
  }

  static void localizeResources(Collection resources, CDASpace space) {
    for (CDAResource resource : resources) {
      CDAType type = resource.type();
      if (ASSET.equals(type) || ENTRY.equals(type)) {
        localize((LocalizedResource) resource, space);
      }
    }
  }

  static void localize(LocalizedResource resource, CDASpace space) {
    resource.setDefaultLocale(space.defaultLocale().code());
    resource.setFallbackLocaleMap(getFallbackLocaleMap(space));
    String resourceLocale = resource.getAttribute("locale");
    if (resourceLocale == null) {
      // sync
      resource.setLocale(resource.defaultLocale());
    } else {
      // normal
      resource.setLocale(resourceLocale);
      normalizeFields(resource);
    }
  }

  private static Map getFallbackLocaleMap(CDASpace space) {
    final Map fallbackLocales = new HashMap(space.locales().size());

    for (final CDALocale locale : space.locales()) {
      final String fallback = locale.fallbackLocaleCode();
      if (fallback != null && !"".equals(fallback)) {
        fallbackLocales.put(locale.code, fallback);
      }
    }

    return fallbackLocales;
  }

  static void normalizeFields(LocalizedResource resource) {
    Map fields = new HashMap();
    for (String key : resource.fields.keySet()) {
      Object value = resource.fields.get(key);
      if (value == null) {
        continue;
      } else if (resourceContainsLocaleMap(resource, value)) {
        fields.put(key, value);
      } else {
        Map map = new HashMap();
        map.put(resource.locale(), value);
        fields.put(key, map);
      }
    }
    resource.fields = fields;
  }

  private static boolean resourceContainsLocaleMap(LocalizedResource resource, Object value) {
    return value instanceof Map
        && ((Map) value).containsKey(resource.locale);
  }

  static void setRawFields(ArrayResource array) {
    for (CDAAsset asset : array.assets().values()) {
      setRawFields(asset);
    }
    for (CDAEntry entry : array.entries().values()) {
      setRawFields(entry);
    }
  }

  @SuppressWarnings("unchecked")
  private static void setRawFields(LocalizedResource resource) {
    Map rawFields = new HashMap();
    for (String key : resource.fields.keySet()) {
      Map map = new HashMap();
      map.putAll((Map) resource.fields.get(key));
      rawFields.put(key, map);
    }
    resource.rawFields = rawFields;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy