/**
   * Return fully resolved Component or Page model based on the given TcmUri by reading and
   * deserializing JSON file from the file system
   *
   * @param tcmUri TcmUri identifing the model to retrieve
   * @return ComponentMeta or PageMeta the fully resolved model; or null, if not found
   */
  @Override
  public <T extends ItemMeta> T read(TcmUri tcmUri) {
    log.debug("Read model for {}", tcmUri);

    String path = pathMapper.getModelAbsolutePath(tcmUri);
    File file = new File(path);
    if (!file.exists()) {
      log.debug("File with TcmUri {} not found at path file {}", tcmUri, path);
      return null;
    }

    try {
      Class<T> aClass = ModelUtils.getClass(tcmUri);
      T model = serializer.deserialize(file, aClass);
      log.debug("Return model {} from file {}", model, file);
      return model;
    } catch (SerializationException se) {
      log.error("Error deserializing model " + tcmUri + " from file " + path, se);
      throw new ModelException(se);
    }
  }
  /**
   * Persist the given Component or Page model by serializing it to JSON and writing it to the file
   * system
   *
   * @param model ComponentMeta or PageMeta to persist
   * @return ComponentMeta or PageMeta the persisted model
   */
  @Override
  public <T extends ItemMeta> T update(T model) {
    log.debug("Update model {}", model);

    TcmUri tcmUri = model.getTcmUri();
    String path = pathMapper.getModelAbsolutePath(tcmUri);
    File file = new File(path);

    if (!file.exists()) {
      File directory = file.getParentFile();
      if (!directory.exists()) {
        if (!directory.mkdirs()) {
          log.error("Directory {} was not created", directory);
        }
      }
    }

    serializer.serialize(file, model);
    log.debug("Done update model {} to file {}", tcmUri, file);

    return model;
  }