Polish
This commit is contained in:
parent
805b7159b0
commit
d2c6ea5b1b
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Segment> segments = parseContent(fullContent);
|
||||
String cssContent = new String(bytes, DEFAULT_CHARSET);
|
||||
List<ContentChunkInfo> 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<Segment> parseContent(String fullContent) {
|
||||
|
||||
List<Segment> links = new ArrayList<>();
|
||||
for (LinkParser parser : this.linkParsers) {
|
||||
links.addAll(parser.parseLinks(fullContent));
|
||||
}
|
||||
|
||||
private List<ContentChunkInfo> parseContent(String cssContent) {
|
||||
SortedSet<ContentChunkInfo> links = new TreeSet<>();
|
||||
this.linkParsers.forEach(parser -> parser.parse(cssContent, links));
|
||||
if (links.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Collections.sort(links);
|
||||
|
||||
int index = 0;
|
||||
List<Segment> allSegments = new ArrayList<>(links);
|
||||
for (Segment link : links) {
|
||||
allSegments.add(new Segment(index, link.getStart(), false));
|
||||
List<ContentChunkInfo> 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<Segment> parseLinks(String fullContent);
|
||||
void parse(String cssContent, SortedSet<ContentChunkInfo> 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<Segment> parseLinks(String fullContent) {
|
||||
Set<Segment> linksToAdd = new HashSet<>(8);
|
||||
int index = 0;
|
||||
do {
|
||||
index = fullContent.indexOf(getKeyword(), index);
|
||||
if (index == -1) {
|
||||
break;
|
||||
public void parse(String content, SortedSet<ContentChunkInfo> 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<Segment> linksToAdd) {
|
||||
protected int extractLink(int index, char endChar, String content, Set<ContentChunkInfo> 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<Segment> linksToAdd);
|
||||
protected abstract int extractUnquotedLink(int position, String content,
|
||||
Set<ContentChunkInfo> linksToAdd);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -229,14 +215,14 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected int extractLink(int index, String content, Set<Segment> linksToAdd) {
|
||||
if (content.substring(index, index + 4).equals("url(")) {
|
||||
// Ignore, UrlLinkParser will take care
|
||||
protected int extractUnquotedLink(int position, String content, Set<ContentChunkInfo> 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<Segment> linksToAdd) {
|
||||
protected int extractUnquotedLink(int position, String content, Set<ContentChunkInfo> result) {
|
||||
// A url() function without unquoted
|
||||
return addLink(index - 1, ")", content, linksToAdd);
|
||||
return extractLink(position - 1, ')', content, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class Segment implements Comparable<Segment> {
|
||||
private static class ContentChunkInfo implements Comparable<ContentChunkInfo> {
|
||||
|
||||
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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue