/**
   * Create new Component or Page model without persisting it to file system and populates only its
   * TcmUri
   *
   * @param tcmUri TcmUri identifing the model to create
   * @return ComponentMeta or PageMeta newly created
   */
  @Override
  public <T extends ItemMeta> T create(TcmUri tcmUri) {
    log.debug("Create model for {}", tcmUri);

    T result;
    Class<T> aClass = ModelUtils.getClass(tcmUri);
    try {
      result = aClass.newInstance();
      Method setTcmUri = aClass.getMethod("setTcmUri", TcmUri.class);
      setTcmUri.invoke(result, tcmUri);
    } catch (InstantiationException
        | IllegalAccessException
        | NoSuchMethodException
        | InvocationTargetException e) {
      log.error("Error instantiating model for type " + aClass, e);
      throw new ModelException(e);
    }

    return result;
  }
  /**
   * 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);
    }
  }