class SAML2FileSystemMetadataGenerator extends BaseSAML2MetadataGenerator {

    private final Resource metadataResource;

    /** {@inheritDoc} */
    @Override
    protected AbstractMetadataResolver createMetadataResolver() throws Exception {
        if (metadataResource != null) {
            return new FilesystemMetadataResolver(metadataResource.getFile());
        }
        return null;
    }

    /** {@inheritDoc} */
    @Override
    public boolean storeMetadata(final String metadata, final boolean force) throws Exception {<FILL_FUNCTION_BODY>}
}

        if (metadataResource == null || CommonHelper.isBlank(metadata)) {
            logger.info("No metadata or resource is provided");
            return false;
        }
        if (!(metadataResource instanceof WritableResource)) {
            logger.warn("Unable to store metadata, as resource is not writable");
            return false;
        }

        if (metadataResource.exists() && !force) {
            logger.info("Metadata file already exists at {}.", metadataResource.getFile());
        } else {
            logger.info("Writing metadata to {}", metadataResource.getFilename());
            val parent = metadataResource.getFile().getParentFile();
            if (parent != null) {
                logger.debug("Attempting to create directory structure for: {}", parent.getCanonicalPath());
                if (!parent.exists() && !parent.mkdirs()) {
                    logger.warn("Could not construct the directory structure for metadata: {}", parent.getCanonicalPath());
                }
            }
            val transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
            val result = new StreamResult(new StringWriter());
            Source source = new StreamSource(new StringReader(metadata));
            transformer.transform(source, result);

            val destination = WritableResource.class.cast(metadataResource);
            try (var spMetadataOutputStream = destination.getOutputStream()) {
                spMetadataOutputStream.write(result.getWriter().toString().getBytes(StandardCharsets.UTF_8));
            }
            if (destination.exists()) {
                if (isSignMetadata()) {
                    getMetadataSigner().sign(metadataResource.getFile());
                }
                return true;
            }
        }
        return false;
    
<methods>public non-sealed void <init>() ,public org.opensaml.saml.saml2.metadata.EntityDescriptor buildEntityDescriptor() ,public org.opensaml.saml.metadata.resolver.MetadataResolver buildMetadataResolver() throws java.lang.Exception,public List<java.lang.String> getBlackListedSignatureSigningAlgorithms() ,public java.lang.String getMetadata(org.opensaml.saml.saml2.metadata.EntityDescriptor) throws java.lang.Exception,public List<java.lang.String> getSignatureAlgorithms() ,public List<java.lang.String> getSignatureReferenceDigestMethods() <variables>protected java.lang.String assertionConsumerServiceUrl,protected boolean authnRequestSigned,protected List<java.lang.String> blackListedSignatureSigningAlgorithms,protected final org.opensaml.core.xml.XMLObjectBuilderFactory builderFactory,private List<org.pac4j.saml.metadata.SAML2MetadataContactPerson> contactPersons,protected org.pac4j.saml.crypto.CredentialProvider credentialProvider,protected int defaultACSIndex,protected org.opensaml.xmlsec.SignatureSigningConfiguration defaultSignatureSigningConfiguration,protected java.lang.String entityId,protected final org.opensaml.xmlsec.algorithm.AlgorithmRegistry globalAlgorithmRegistry,protected final org.slf4j.Logger logger,protected final org.opensaml.core.xml.io.MarshallerFactory marshallerFactory,private org.pac4j.saml.metadata.SAML2MetadataSigner metadataSigner,private List<org.pac4j.saml.metadata.SAML2MetadataUIInfo> metadataUIInfos,protected java.lang.String nameIdPolicyFormat,protected java.lang.String requestInitiatorLocation,protected List<org.pac4j.saml.metadata.SAML2ServiceProviderRequestedAttribute> requestedAttributes,protected java.lang.String responseBindingType,protected boolean signMetadata,protected List<java.lang.String> signatureAlgorithms,protected List<java.lang.String> signatureReferenceDigestMethods,protected java.lang.String singleLogoutServiceUrl,private List<java.lang.String> supportedProtocols,protected boolean wantAssertionSigned