class AbstractCache implements Cache {



    public boolean hasCacheForFile(File file) throws CacheException {
        try {
            return getCachedFile(file).exists();
        } catch (CacheException ex) {
            throw new CacheException(ex);
        }
    }

    /**
     * Get a <code>File</code> object describing the cache file.
     *
     * @param file the file to find the cache for
     * @return file that might contain cached object for <code>file</code>
     * @throws CacheException on error
     */
    File getCachedFile(File file) throws CacheException {

        RuntimeEnvironment env = RuntimeEnvironment.getInstance();

        StringBuilder sb = new StringBuilder();
        sb.append(env.getDataRootPath());
        sb.append(File.separatorChar);
        sb.append(getCacheDirName());

        try {
            String add = env.getPathRelativeToSourceRoot(file);
            if (add.length() == 0) {
                add = File.separator;
            }
            sb.append(add);
        } catch (ForbiddenSymlinkException | IOException e) {
            throw new CacheException(String.format("Failed to get path relative to source root for '%s'", file), e);
        }

        String suffix = getCacheFileSuffix();
        if (suffix != null && !suffix.isEmpty()) {
            return new File(TandemPath.join(sb.toString(), suffix));
        }

        return new File(sb.toString());
    }

    public List<String> clearCache(Collection<RepositoryInfo> repositories) {
        List<String> clearedRepos = new ArrayList<>();

        for (RepositoryInfo repo : repositories) {
            try {
                this.clear(repo);
                clearedRepos.add(repo.getDirectoryNameRelative());
                LOGGER.log(Level.INFO, "{1} cache for ''{0}'' cleared.",
                        new Object[]{repo.getDirectoryName(), this.getInfo()});
            } catch (CacheException e) {
                LOGGER.log(Level.WARNING,
                        "Clearing cache for repository ''{0}'' failed: {1}",
                        new Object[]{repo.getDirectoryName(), e.getLocalizedMessage()});
            }
        }

        return clearedRepos;
    }

    /**
     * Attempt to delete file with its parent.
     * @param file file to delete
     */
    static void clearWithParent(File file) {
        File parent = file.getParentFile();

        if (!file.delete() && file.exists()) {
            LOGGER.log(Level.WARNING, "Failed to remove obsolete cache-file: ''{0}''", file.getAbsolutePath());
        }

        if (parent.delete()) {
            LOGGER.log(Level.FINE, "Removed empty cache dir: ''{0}''", parent.getAbsolutePath());
        }
    }

    public void clearFile(String path) {<FILL_FUNCTION_BODY>}

    public String getCacheFileSuffix() {
        return "";
    }
}

        File historyFile;
        try {
            historyFile = getCachedFile(new File(RuntimeEnvironment.getInstance().getSourceRootPath() + path));
        } catch (CacheException ex) {
            LOGGER.log(Level.WARNING, String.format("cannot get cached file for file '%s'"
                    + " - the cache entry will not be cleared", path), ex);
            return;
        }

        clearWithParent(historyFile);
    
<no_super_class>