private Mono<? extends Resource> transform(String content, Resource resource, ResourceTransformerChain chain, ServerWebExchange exchange) { if (!content.startsWith(MANIFEST_HEADER)) { if (logger.isTraceEnabled()) { logger.trace(exchange.getLogPrefix() + "Skipping " + resource + ": Manifest does not start with 'CACHE MANIFEST'"); } return Mono.just(resource); } return Flux.generate(new LineInfoGenerator(content)) .concatMap(info -> processLine(info, exchange, resource, chain)) .reduce(new ByteArrayOutputStream(), (out, line) -> { writeToByteArrayOutputStream(out, line + "\n"); return out; }) .map(out -> { String hash = DigestUtils.md5DigestAsHex(out.toByteArray()); writeToByteArrayOutputStream(out, "\n" + "# Hash: " + hash); return new TransformedResource(resource, out.toByteArray()); }); }
@Override public Mono<Resource> transform(ServerWebExchange exchange, Resource inputResource, ResourceTransformerChain chain) { return chain.transform(exchange, inputResource) .then(resource -> { String name = resource.getFilename(); if (!this.fileExtension.equals(StringUtils.getFilenameExtension(name))) { return Mono.just(resource); } String content = new String(getResourceBytes(resource), DEFAULT_CHARSET); if (!content.startsWith(MANIFEST_HEADER)) { if (logger.isTraceEnabled()) { logger.trace("Manifest should start with 'CACHE MANIFEST', skip: " + resource); } return Mono.just(resource); } if (logger.isTraceEnabled()) { logger.trace("Transforming resource: " + resource); } return Flux.generate(new LineGenerator(content)) .concatMap(info -> processLine(info, exchange, resource, chain)) .collect(() -> new LineAggregator(resource, content), LineAggregator::add) .then(aggregator -> Mono.just(aggregator.createResource())); }); }