From d2c6ea5b1ba61fe24854a30edb4b220fd91c11f3 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 14 Jul 2017 13:22:58 +0200 Subject: [PATCH] Polish --- .../resource/AppCacheManifestTransformer.java | 2 +- .../resource/CssLinkResourceTransformer.java | 140 ++++++++---------- 2 files changed, 64 insertions(+), 78 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/AppCacheManifestTransformer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/AppCacheManifestTransformer.java index f6cc367f166..24b4e719e91 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/AppCacheManifestTransformer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/AppCacheManifestTransformer.java @@ -125,7 +125,7 @@ public class AppCacheManifestTransformer extends ResourceTransformerSupport { return Flux.generate(new LineGenerator(content)) .concatMap(info -> processLine(info, exchange, resource, chain)) .collect(() -> new LineAggregator(resource, content), LineAggregator::add) - .flatMap(aggregator -> Mono.just(aggregator.createResource())); + .map(LineAggregator::createResource); }); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java index 46fbc89ec24..8bf8b71e3d3 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java @@ -22,9 +22,10 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -83,27 +84,27 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport { logger.trace("Transforming resource: " + newResource); } - byte[] bytes = new byte[0]; + byte[] bytes; try { bytes = FileCopyUtils.copyToByteArray(newResource.getInputStream()); } catch (IOException ex) { return Mono.error(Exceptions.propagate(ex)); } - String fullContent = new String(bytes, DEFAULT_CHARSET); - List segments = parseContent(fullContent); + String cssContent = new String(bytes, DEFAULT_CHARSET); + List contentChunkInfos = parseContent(cssContent); - if (segments.isEmpty()) { + if (contentChunkInfos.isEmpty()) { if (logger.isTraceEnabled()) { logger.trace("No links found."); } return Mono.just(newResource); } - return Flux.fromIterable(segments) - .concatMap(segment -> { - String segmentContent = segment.getContent(fullContent); - if (segment.isLink() && !hasScheme(segmentContent)) { + return Flux.fromIterable(contentChunkInfos) + .concatMap(contentChunkInfo -> { + String segmentContent = contentChunkInfo.getContent(cssContent); + if (contentChunkInfo.isLink() && !hasScheme(segmentContent)) { String link = toAbsolutePath(segmentContent, exchange); return resolveUrlPath(link, exchange, newResource, transformerChain) .defaultIfEmpty(segmentContent); @@ -116,39 +117,30 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport { writer.write(chunk); return writer; }) - .flatMap(writer -> { + .map(writer -> { byte[] newContent = writer.toString().getBytes(DEFAULT_CHARSET); - return Mono.just(new TransformedResource(resource, newContent)); + return new TransformedResource(resource, newContent); }); }); } - private List parseContent(String fullContent) { - - List links = new ArrayList<>(); - for (LinkParser parser : this.linkParsers) { - links.addAll(parser.parseLinks(fullContent)); - } - + private List parseContent(String cssContent) { + SortedSet links = new TreeSet<>(); + this.linkParsers.forEach(parser -> parser.parse(cssContent, links)); if (links.isEmpty()) { return Collections.emptyList(); } - - Collections.sort(links); - int index = 0; - List allSegments = new ArrayList<>(links); - for (Segment link : links) { - allSegments.add(new Segment(index, link.getStart(), false)); + List result = new ArrayList<>(); + for (ContentChunkInfo link : links) { + result.add(new ContentChunkInfo(index, link.getStart(), false)); + result.add(link); index = link.getEnd(); } - if (index < fullContent.length()) { - allSegments.add(new Segment(index, fullContent.length(), false)); + if (index < cssContent.length()) { + result.add(new ContentChunkInfo(index, cssContent.length(), false)); } - - Collections.sort(allSegments); - - return allSegments; + return result; } private boolean hasScheme(String link) { @@ -157,66 +149,60 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport { } + /** + * Extract content chunks that represent links. + */ @FunctionalInterface protected interface LinkParser { - Set parseLinks(String fullContent); + void parse(String cssContent, SortedSet result); } protected static abstract class AbstractLinkParser implements LinkParser { - /** Return the keyword to use to search for links. */ + /** Return the keyword to use to search for links, e.g. "@import", "url(" */ protected abstract String getKeyword(); @Override - public Set parseLinks(String fullContent) { - Set linksToAdd = new HashSet<>(8); - int index = 0; - do { - index = fullContent.indexOf(getKeyword(), index); - if (index == -1) { - break; + public void parse(String content, SortedSet result) { + int position = 0; + while (true) { + position = content.indexOf(getKeyword(), position); + if (position == -1) { + return; } - index = skipWhitespace(fullContent, index + getKeyword().length()); - if (fullContent.charAt(index) == '\'') { - index = addLink(index, "'", fullContent, linksToAdd); + position += getKeyword().length(); + while (Character.isWhitespace(content.charAt(position))) { + position++; } - else if (fullContent.charAt(index) == '"') { - index = addLink(index, "\"", fullContent, linksToAdd); + if (content.charAt(position) == '\'') { + position = extractLink(position, '\'', content, result); + } + else if (content.charAt(position) == '"') { + position = extractLink(position, '"', content, result); } else { - index = extractLink(index, fullContent, linksToAdd); + position = extractUnquotedLink(position, content, result); } } - while (true); - return linksToAdd; } - private int skipWhitespace(String content, int index) { - while (true) { - if (Character.isWhitespace(content.charAt(index))) { - index++; - continue; - } - return index; - } - } - - protected int addLink(int index, String endKey, String content, Set linksToAdd) { + protected int extractLink(int index, char endChar, String content, Set result) { int start = index + 1; - int end = content.indexOf(endKey, start); - linksToAdd.add(new Segment(start, end, true)); - return end + endKey.length(); + int end = content.indexOf(endChar, start); + result.add(new ContentChunkInfo(start, end, true)); + return end + 1; } /** * Invoked after a keyword match, after whitespaces removed, and when * the next char is neither a single nor double quote. */ - protected abstract int extractLink(int index, String content, Set linksToAdd); + protected abstract int extractUnquotedLink(int position, String content, + Set linksToAdd); } @@ -229,14 +215,14 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport { } @Override - protected int extractLink(int index, String content, Set linksToAdd) { - if (content.substring(index, index + 4).equals("url(")) { - // Ignore, UrlLinkParser will take care + protected int extractUnquotedLink(int position, String content, Set result) { + if (content.substring(position, position + 4).equals("url(")) { + // Ignore, UrlFunctionContentParser will take care } else if (logger.isErrorEnabled()) { - logger.error("Unexpected syntax for @import link at index " + index); + logger.error("Unexpected syntax for @import link at index " + position); } - return index; + return position; } } @@ -249,26 +235,26 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport { } @Override - protected int extractLink(int index, String content, Set linksToAdd) { + protected int extractUnquotedLink(int position, String content, Set result) { // A url() function without unquoted - return addLink(index - 1, ")", content, linksToAdd); + return extractLink(position - 1, ')', content, result); } } - private static class Segment implements Comparable { + private static class ContentChunkInfo implements Comparable { private final int start; private final int end; - private final boolean link; + private final boolean isLink; - public Segment(int start, int end, boolean isLink) { + ContentChunkInfo(int start, int end, boolean isLink) { this.start = start; this.end = end; - this.link = isLink; + this.isLink = isLink; } @@ -281,7 +267,7 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport { } public boolean isLink() { - return this.link; + return this.isLink; } public String getContent(String fullContent) { @@ -289,7 +275,7 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport { } @Override - public int compareTo(Segment other) { + public int compareTo(ContentChunkInfo other) { return (this.start < other.start ? -1 : (this.start == other.start ? 0 : 1)); } @@ -298,8 +284,8 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport { if (this == obj) { return true; } - if (obj != null && obj instanceof Segment) { - Segment other = (Segment) obj; + if (obj != null && obj instanceof ContentChunkInfo) { + ContentChunkInfo other = (ContentChunkInfo) obj; return (this.start == other.start && this.end == other.end); } return false;