class OpearFile implements Opear {

    public static Result<OpearFile> fromJar(final @NotNull JarFile jarFile, final @NotNull File cacheBaseDir) {
        return getHashCacheKey(jarFile.getName()).flatMap(cacheKey -> {
            return result1(JarFile::getManifest).apply(jarFile)
                    .flatMap(OpearFile::validateOpearManifest)
                    .flatMap(metadata -> {
                        final File cacheDir = new File(cacheBaseDir, cacheKey);
                        if (cacheDir.isDirectory()) {
                            return fromDirectory(cacheDir);
                        } else {
                            if (!cacheDir.mkdirs()) {
                                return Result.failure(format("failed to create cache dir %s for specified opear file %s",
                                        cacheDir.getPath(), jarFile.getName()));
                            } else {
                                return cacheJar(jarFile, cacheDir).flatMap(OpearFile::fromDirectory);
                            }
                        }
                    });
        });
    }

      OpearFile(final File cacheDir, final OpearMetadata metadata);

}