public static String constructFilename(final String executionUuid,
                                           final long id,
                                           final String template,
                                           final AttributeMap attributeMap,
                                           final String... fileExtensions) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Using" +
                    " template " +
                    template +
                    " and fileExtensions " +
                    Arrays.toString(fileExtensions));
        }

        final String idStr = StringIdUtil.idToString(id);
        final String pathIdStr = idToPathId(idStr);

        String path = template;
        // Replace path template with header and time values.
        path = PathCreator.replaceAll(path, attributeMap);
        // Replace executionUuid variable with execution UUID.
        path = PathCreator.replace(path, EXECUTION_UUID, executionUuid);
        // Replace pathId variable with path id.
        path = PathCreator.replace(path, PATH_ID, pathIdStr);
        // Replace id variable with file id.
        path = PathCreator.replace(path, ID, idStr);

        // Check for any remaining variables.
        final String[] remainingVars = PathCreator.findVars(path);
        if (remainingVars.length > 0) {
            LOGGER.warn("Unused variables found: " + Arrays.toString(remainingVars));

            // Replace all missing values with an underscore.
            for (final String remainingVar : remainingVars) {
                path = PathCreator.replace(path, remainingVar, MISSING_VALUE);
            }
        }

        // Clean the path.
        path = clean(path);

        // Append file extensions.
        if (fileExtensions != null) {
            final StringBuilder sb = new StringBuilder(path);
            for (String extension : fileExtensions) {
                if (extension != null) {
                    sb.append(extension);
                }
            }
            path = sb.toString();
        }

        return path;
    }
Clean part of a path so that it doesn't contain invalid characters and is less than the maximum length of a part.

@param part The part of the path to clean.
@return A cleaned path part.
stroom-data/stroom-data-zip/src/main/java/stroom/data/zip/StroomFileNameUtil.java