Repository: tapestry-5 Updated Branches: refs/heads/master 789e395e6 -> 475af4cc9
Convert ContentType to be an immutable data class Convert some usages of String (for content type) to use ContentType Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/85622bc3 Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/85622bc3 Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/85622bc3 Branch: refs/heads/master Commit: 85622bc3510757c81e3634c205bd0ba947b9d93d Parents: 789e395 Author: Howard M. Lewis Ship <[email protected]> Authored: Wed Sep 3 13:37:23 2014 -0700 Committer: Howard M. Lewis Ship <[email protected]> Committed: Wed Sep 3 13:37:23 2014 -0700 ---------------------------------------------------------------------- 54_RELEASE_NOTES.md | 6 + .../java/org/apache/tapestry5/ContentType.java | 179 +++++++++---------- .../tapestry5/internal/InternalConstants.java | 6 + .../AjaxPartialResponseRendererImpl.java | 16 +- .../services/JSONArrayEventResultProcessor.java | 25 ++- .../services/PageContentTypeAnalyzerImpl.java | 4 +- .../internal/services/ResourceStreamerImpl.java | 2 +- .../ResponseCompressionAnalyzerImpl.java | 11 +- .../services/assets/CSSURLRewriter.java | 30 ++-- .../internal/services/assets/DelegatingSRS.java | 3 +- .../assets/JavaScriptStackAssemblerImpl.java | 5 +- .../services/assets/StreamableResourceImpl.java | 11 +- .../assets/StreamableResourceSourceImpl.java | 9 +- .../services/assets/UTF8ForTextAssets.java | 10 +- .../services/javascript/ModuleManagerImpl.java | 5 +- .../internal/test/PageTesterModule.java | 7 +- .../services/ResponseCompressionAnalyzer.java | 5 +- .../services/assets/ResourceTransformer.java | 5 +- .../services/assets/StreamableResource.java | 9 +- .../assets/StreamableResourceSource.java | 9 +- .../tapestry5/util/TextStreamResponse.java | 4 +- .../apache/tapestry5/root/ContentTypeTest.java | 71 +++++--- .../webresources/CoffeeScriptCompiler.java | 10 +- .../DelegatingResourceTransformer.java | 32 ++++ .../webresources/LessResourceTransformer.java | 9 +- .../ResourceTransformerFactoryImpl.java | 48 ++--- 26 files changed, 291 insertions(+), 240 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/54_RELEASE_NOTES.md ---------------------------------------------------------------------- diff --git a/54_RELEASE_NOTES.md b/54_RELEASE_NOTES.md index 19a598e..4b35667 100644 --- a/54_RELEASE_NOTES.md +++ b/54_RELEASE_NOTES.md @@ -455,3 +455,9 @@ Tapestry now determines if a client-persistent field is mutable and contains cha checks as for session-persistent objects (the OptimizedSessionPersistedObject interface and so forth). Previously, Tapestry would load a mutable object into a field, but a change to the internal state of that mutable field would not always be preserved in the serialized object data attached to links. + +## ContentType + +The ContentType objects, used to represent a content types such as "text/html" in a structured manner, +has been revised significantly in 5.4; it is now an immutable data type. In addition, a few scattered +interfaces that used a String content type have been changed to use the ContentType class instead. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/ContentType.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/ContentType.java b/tapestry-core/src/main/java/org/apache/tapestry5/ContentType.java index 87f0a1b..93739f3 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/ContentType.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/ContentType.java @@ -1,5 +1,3 @@ -// Copyright 2007-2013 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -14,55 +12,84 @@ package org.apache.tapestry5; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - import org.apache.tapestry5.internal.InternalConstants; import org.apache.tapestry5.ioc.internal.util.CollectionFactory; import org.apache.tapestry5.ioc.internal.util.InternalUtils; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * Represents an HTTP content type. Allows to set various elements like the MIME type, the character set, and other * parameters. This is similar to a number of other implementations of the same concept in JAF, etc. We have created * this simple implementation to avoid including the whole libraries. + * <p/> + * As of Tapestry 5.4, this is now an immutable data type. */ public final class ContentType { - private String baseType = ""; + private final String baseType; - private String subType = ""; + private final String subType; - private final Map<String, String> parameters = CollectionFactory.newCaseInsensitiveMap(); + private final Map<String, String> parameters; - /** - * Creates a new empty content type. - */ - public ContentType() - { - } + private static final Pattern PATTERN = Pattern.compile("^(.+)/([^;]+)(;(.+=[^;]+))*$"); /** * Creates a new content type from the argument. The format of the argument has to be basetype/subtype(;key=value)* * - * @param contentType the content type that needs to be represented + * @param contentType + * the content type that needs to be represented */ public ContentType(String contentType) { - parse(contentType); + Matcher matcher = PATTERN.matcher(contentType); + + if (!matcher.matches()) + { + throw new IllegalArgumentException(String.format("Not a parseable content type '%s'.", contentType)); + } + + this.baseType = matcher.group(1); + this.subType = matcher.group(2); + this.parameters = parseKeyValues(matcher.group(4)); } - /** - * Creates a new content type with the given MIME type and charset - */ - public ContentType(String contentType, String charset) + private ContentType(String baseType, String subType, Map<String, String> parameters) { - this(contentType); - - setParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER, charset); + this.baseType = baseType; + this.subType = subType; + this.parameters = parameters; } + private static Map<String, String> parseKeyValues(String keyValues) + { + if (keyValues == null) + { + return Collections.emptyMap(); + } + + Map<String, String> parameters = CollectionFactory.newCaseInsensitiveMap(); + + StringTokenizer tk = new StringTokenizer(keyValues, ";"); + + while (tk.hasMoreTokens()) + { + String token = tk.nextToken(); + int sep = token.indexOf('='); + + parameters.put(token.substring(0, sep), token.substring(sep + 1)); + } + + return parameters; + } + /** * Returns true only if the other object is another instance of ContentType, and has the same baseType, subType and * set of parameters. @@ -88,15 +115,6 @@ public final class ContentType } /** - * @param baseType - */ - public void setBaseType(String baseType) - { - assert baseType != null; - this.baseType = baseType; - } - - /** * @return the sub-type of the content type */ public String getSubType() @@ -105,16 +123,7 @@ public final class ContentType } /** - * @param subType - */ - public void setSubType(String subType) - { - assert subType != null; - this.subType = subType; - } - - /** - * @return the MIME type of the content type + * @return the MIME type of the content type (the base type and the subtype, seperated with a '/'). */ public String getMimeType() { @@ -130,7 +139,7 @@ public final class ContentType } /** - * @return the character set (the "charset" parameter) or null. + * @return the character set (the "charset" parameter) or null. */ public String getCharset() { @@ -138,7 +147,8 @@ public final class ContentType } /** - * @param key the name of the content type parameter + * @param key + * the name of the content type parameter * @return the value of the content type parameter */ public String getParameter(String key) @@ -147,72 +157,59 @@ public final class ContentType return parameters.get(key); } - /** - * @param key the name of the content type parameter - * @param value the value of the content type parameter - */ - public void setParameter(String key, String value) + private String unparse() { - assert key != null; - assert value != null; - parameters.put(key, value); + StringBuilder buffer = new StringBuilder(getMimeType()); + + for (String parameterName : getParameterNames()) + { + buffer.append(";"); + buffer.append(parameterName); + buffer.append("="); + buffer.append(parameters.get(parameterName)); + } + + return buffer.toString(); } /** - * Parses the argument and configures the content type accordingly. The format of the argument has to be - * type/subtype(;key=value)* + * Returns a new content type with the indicated parameter. * - * @param contentType the content type that needs to be represented + * @since 5.4 */ - public void parse(String contentType) + public ContentType withParameter(String key, String value) { - baseType = ""; - subType = ""; - parameters.clear(); - - StringTokenizer tokens = new StringTokenizer(contentType, ";"); - if (!tokens.hasMoreTokens()) return; + assert InternalUtils.isNonBlank(key); + assert InternalUtils.isNonBlank(value); - String mimeType = tokens.nextToken(); - StringTokenizer mimeTokens = new StringTokenizer(mimeType, "/"); - setBaseType(mimeTokens.hasMoreTokens() ? mimeTokens.nextToken() : ""); - setSubType(mimeTokens.hasMoreTokens() ? mimeTokens.nextToken() : ""); + Map<String, String> newParameters = CollectionFactory.newCaseInsensitiveMap(); - while (tokens.hasMoreTokens()) - { - String parameter = tokens.nextToken(); + newParameters.putAll(parameters); + newParameters.put(key, value); - StringTokenizer parameterTokens = new StringTokenizer(parameter, "="); - String key = parameterTokens.hasMoreTokens() ? parameterTokens.nextToken() : ""; - String value = parameterTokens.hasMoreTokens() ? parameterTokens.nextToken() : ""; - setParameter(key, value); - } + return new ContentType(baseType, subType, newParameters); } - /** - * @return the string representation of this content type - */ - public String unparse() + public ContentType withCharset(String charset) { - StringBuilder buffer = new StringBuilder(getMimeType()); - - for (String parameterName : getParameterNames()) - { - buffer.append(";"); - buffer.append(parameterName); - buffer.append("="); - buffer.append(parameters.get(parameterName)); - } - - return buffer.toString(); + return withParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER, charset); } /** - * @return the string representation of this content type. Same as unparse(). + * @return the string representation of this content type. */ @Override public String toString() { return unparse(); } + + /** + * @return true if the content type includes parameters (such as 'charset'). + * @since 5.4 + */ + public boolean hasParameters() + { + return !parameters.isEmpty(); + } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java index 9ad6b7c..a308268 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java @@ -12,6 +12,7 @@ package org.apache.tapestry5.internal; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.dom.MarkupModel; import org.apache.tapestry5.ioc.util.TimeInterval; import org.apache.tapestry5.services.javascript.JavaScriptStack; @@ -207,4 +208,9 @@ public final class InternalConstants * @since 5.4 */ public static final String SUPPRESS_NAMESPACED_IDS = "t:suppress-namespaced-ids"; + + /** + * @since 5.4 + */ + public static final ContentType JAVASCRIPT_CONTENT_TYPE = new ContentType("text/javascript"); } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxPartialResponseRendererImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxPartialResponseRendererImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxPartialResponseRendererImpl.java index 8def717..22ffce9 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxPartialResponseRendererImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AjaxPartialResponseRendererImpl.java @@ -1,5 +1,3 @@ -// Copyright 2007-2014 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -23,7 +21,10 @@ import org.apache.tapestry5.ioc.IOOperation; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.ioc.annotations.Symbol; import org.apache.tapestry5.json.JSONObject; -import org.apache.tapestry5.services.*; +import org.apache.tapestry5.services.MarkupWriterFactory; +import org.apache.tapestry5.services.PartialMarkupRenderer; +import org.apache.tapestry5.services.Request; +import org.apache.tapestry5.services.Response; import java.io.IOException; import java.io.PrintWriter; @@ -38,10 +39,10 @@ public class AjaxPartialResponseRendererImpl implements AjaxPartialResponseRende private final PartialMarkupRenderer partialMarkupRenderer; - private final String outputEncoding; - private final boolean compactJSON; + private final ContentType contentType; + public AjaxPartialResponseRendererImpl(MarkupWriterFactory factory, Request request, @@ -61,8 +62,9 @@ public class AjaxPartialResponseRendererImpl implements AjaxPartialResponseRende this.request = request; this.response = response; this.partialMarkupRenderer = partialMarkupRenderer; - this.outputEncoding = outputEncoding; this.compactJSON = compactJSON; + + contentType = new ContentType(InternalConstants.JSON_MIME_TYPE).withCharset(outputEncoding); } public void renderPartialPageMarkup(final JSONObject reply) throws IOException @@ -77,8 +79,6 @@ public class AjaxPartialResponseRendererImpl implements AjaxPartialResponseRende // separated, and trying to keep stateless and stateful (i.e., perthread scope) services // separated. So we inform the stateful queue service what it needs to do here ... - ContentType contentType = new ContentType(InternalConstants.JSON_MIME_TYPE, outputEncoding); - String pageName = (String) request.getAttribute(InternalConstants.PAGE_NAME_ATTRIBUTE_NAME); MarkupWriter writer = factory.newPartialMarkupWriter(pageName); http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/JSONArrayEventResultProcessor.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/JSONArrayEventResultProcessor.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/JSONArrayEventResultProcessor.java index 5da19fb..0e650b9 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/JSONArrayEventResultProcessor.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/JSONArrayEventResultProcessor.java @@ -1,5 +1,3 @@ -// Copyright 2008, 2010 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -14,9 +12,6 @@ package org.apache.tapestry5.internal.services; -import java.io.IOException; -import java.io.PrintWriter; - import org.apache.tapestry5.ContentType; import org.apache.tapestry5.SymbolConstants; import org.apache.tapestry5.internal.InternalConstants; @@ -25,31 +20,33 @@ import org.apache.tapestry5.json.JSONArray; import org.apache.tapestry5.services.ComponentEventResultProcessor; import org.apache.tapestry5.services.Response; +import java.io.IOException; +import java.io.PrintWriter; + public class JSONArrayEventResultProcessor implements ComponentEventResultProcessor<JSONArray> { private final Response response; - private final String outputEncoding; - private final boolean compactJSON; + private final ContentType contentType; + public JSONArrayEventResultProcessor(Response response, - @Symbol(SymbolConstants.CHARSET) - String outputEncoding, + @Symbol(SymbolConstants.CHARSET) + String outputEncoding, - @Symbol(SymbolConstants.COMPACT_JSON) - boolean compactJSON) + @Symbol(SymbolConstants.COMPACT_JSON) + boolean compactJSON) { this.response = response; - this.outputEncoding = outputEncoding; this.compactJSON = compactJSON; + + contentType = new ContentType(InternalConstants.JSON_MIME_TYPE).withCharset(outputEncoding); } public void processResultValue(JSONArray value) throws IOException { - ContentType contentType = new ContentType(InternalConstants.JSON_MIME_TYPE, outputEncoding); - PrintWriter pw = response.getPrintWriter(contentType.toString()); value.print(pw, compactJSON); http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageContentTypeAnalyzerImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageContentTypeAnalyzerImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageContentTypeAnalyzerImpl.java index dd2eba1..322ebc7 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageContentTypeAnalyzerImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageContentTypeAnalyzerImpl.java @@ -1,5 +1,3 @@ -// Copyright 2007, 2008, 2010 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -46,6 +44,6 @@ public class PageContentTypeAnalyzerImpl implements PageContentTypeAnalyzer // Draconian but necessary: overwrite the content type they selected with the application-wide output charset. - return new ContentType(contentTypeString, outputCharset); + return new ContentType(contentTypeString).withCharset(outputCharset); } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamerImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamerImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamerImpl.java index 9176555..f939dff 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamerImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResourceStreamerImpl.java @@ -224,7 +224,7 @@ public class ResourceStreamerImpl implements ResourceStreamer responseCustomizer.customizeResponse(streamable, response); } - OutputStream os = response.getOutputStream(streamable.getContentType()); + OutputStream os = response.getOutputStream(streamable.getContentType().toString()); streamable.streamTo(os); http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResponseCompressionAnalyzerImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResponseCompressionAnalyzerImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResponseCompressionAnalyzerImpl.java index 1fd4072..0b393d0 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResponseCompressionAnalyzerImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ResponseCompressionAnalyzerImpl.java @@ -1,5 +1,3 @@ -// Copyright 2009-2013 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -14,8 +12,7 @@ package org.apache.tapestry5.internal.services; -import javax.servlet.http.HttpServletRequest; - +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.SymbolConstants; import org.apache.tapestry5.internal.InternalConstants; import org.apache.tapestry5.internal.TapestryInternalUtils; @@ -23,6 +20,8 @@ import org.apache.tapestry5.ioc.annotations.Symbol; import org.apache.tapestry5.services.ResponseCompressionAnalyzer; import org.apache.tapestry5.services.assets.CompressionAnalyzer; +import javax.servlet.http.HttpServletRequest; + public class ResponseCompressionAnalyzerImpl implements ResponseCompressionAnalyzer { private final HttpServletRequest request; @@ -77,8 +76,8 @@ public class ResponseCompressionAnalyzerImpl implements ResponseCompressionAnaly return false; } - public boolean isGZipEnabled(String contentType) + public boolean isGZipEnabled(ContentType contentType) { - return isGZipSupported() && compressionAnalyzer.isCompressable(contentType); + return isGZipSupported() && compressionAnalyzer.isCompressable(contentType.getMimeType()); } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/CSSURLRewriter.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/CSSURLRewriter.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/CSSURLRewriter.java index 2678411..042781f 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/CSSURLRewriter.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/CSSURLRewriter.java @@ -13,6 +13,7 @@ package org.apache.tapestry5.internal.services.assets; import org.apache.tapestry5.Asset; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.SymbolConstants; import org.apache.tapestry5.ioc.IOOperation; import org.apache.tapestry5.ioc.OperationTracker; @@ -39,8 +40,8 @@ import java.util.regex.Pattern; * One potential problem with URL rewriting is the way that URLs for referenced resources are generated; we are * somewhat banking on the fact that referenced resources are non-compressable images. * - * @since 5.4 * @see SymbolConstants#STRICT_CSS_URL_REWRITING + * @since 5.4 */ public class CSSURLRewriter extends DelegatingSRS { @@ -66,13 +67,15 @@ public class CSSURLRewriter extends DelegatingSRS private final AssetSource assetSource; private final AssetChecksumGenerator checksumGenerator; - + private final Logger logger = LoggerFactory.getLogger(CSSURLRewriter.class); - + private final boolean strictCssUrlRewriting; - public CSSURLRewriter(StreamableResourceSource delegate, OperationTracker tracker, AssetSource assetSource, - AssetChecksumGenerator checksumGenerator, boolean strictCssUrlRewriting) + private final ContentType CSS_CONTENT_TYPE = new ContentType("text/css"); + + public CSSURLRewriter(StreamableResourceSource delegate, OperationTracker tracker, AssetSource assetSource, + AssetChecksumGenerator checksumGenerator, boolean strictCssUrlRewriting) { super(delegate); this.tracker = tracker; @@ -113,7 +116,8 @@ public class CSSURLRewriter extends DelegatingSRS BytestreamCache cache = new BytestreamCache(filtered.getBytes("UTF-8")); - return new StreamableResourceImpl(base.getDescription(), "text/css", + return new StreamableResourceImpl(base.getDescription(), + CSS_CONTENT_TYPE, CompressionStatus.COMPRESSABLE, base.getLastModified(), cache, checksumGenerator, base.getResponseCustomizer()); @@ -162,7 +166,7 @@ public class CSSURLRewriter extends DelegatingSRS Asset asset = assetSource.getAsset(baseResource, url, null); - if (asset != null) + if (asset != null) { String assetURL = asset.toClientURL(); @@ -175,21 +179,19 @@ public class CSSURLRewriter extends DelegatingSRS appendReplacement(matcher, output, assetURL); didReplace = true; - - } - else + + } else { final String message = String.format("URL %s, referenced in file %s, doesn't exist.", url, baseResource.toURL(), baseResource); - if (strictCssUrlRewriting) + if (strictCssUrlRewriting) { throw new RuntimeException(message); - } - else if (logger.isWarnEnabled()) + } else if (logger.isWarnEnabled()) { logger.warn(message); } } - + } if (!didReplace) http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/DelegatingSRS.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/DelegatingSRS.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/DelegatingSRS.java index a06752a..8a18036 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/DelegatingSRS.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/DelegatingSRS.java @@ -14,6 +14,7 @@ package org.apache.tapestry5.internal.services.assets; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.ioc.Resource; import org.apache.tapestry5.services.assets.ResourceDependencies; import org.apache.tapestry5.services.assets.StreamableResource; @@ -37,7 +38,7 @@ public abstract class DelegatingSRS implements StreamableResourceSource this.delegate = delegate; } - public Set<String> fileExtensionsForContentType(String contentType) + public Set<String> fileExtensionsForContentType(ContentType contentType) { return delegate.fileExtensionsForContentType(contentType); } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/JavaScriptStackAssemblerImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/JavaScriptStackAssemblerImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/JavaScriptStackAssemblerImpl.java index db242cc..76a9824 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/JavaScriptStackAssemblerImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/JavaScriptStackAssemblerImpl.java @@ -13,6 +13,7 @@ package org.apache.tapestry5.internal.services.assets; import org.apache.tapestry5.Asset; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.SymbolConstants; import org.apache.tapestry5.ioc.Resource; import org.apache.tapestry5.ioc.annotations.Symbol; @@ -32,9 +33,9 @@ import java.util.regex.Pattern; public class JavaScriptStackAssemblerImpl implements JavaScriptStackAssembler { - private static final String JAVASCRIPT_CONTENT_TYPE = "text/javascript;charset=utf-8"; + private static final ContentType JAVASCRIPT_CONTENT_TYPE = new ContentType("text/javascript;charset=utf-8"); - private ThreadLocale threadLocale; + private final ThreadLocale threadLocale; private final ResourceChangeTracker resourceChangeTracker; http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceImpl.java index e245f64..40a4e31 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceImpl.java @@ -12,6 +12,7 @@ package org.apache.tapestry5.internal.services.assets; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.services.Response; import org.apache.tapestry5.services.assets.AssetChecksumGenerator; import org.apache.tapestry5.services.assets.CompressionStatus; @@ -24,7 +25,9 @@ import java.io.OutputStream; public class StreamableResourceImpl implements StreamableResource { - protected final String description, contentType; + protected final String description; + + private final ContentType contentType; protected final CompressionStatus compression; @@ -36,7 +39,7 @@ public class StreamableResourceImpl implements StreamableResource protected final ResponseCustomizer responseCustomizer; - public StreamableResourceImpl(String description, String contentType, CompressionStatus compression, long lastModified, BytestreamCache bytestreamCache, AssetChecksumGenerator assetChecksumGenerator, ResponseCustomizer responseCustomizer) + public StreamableResourceImpl(String description, ContentType contentType, CompressionStatus compression, long lastModified, BytestreamCache bytestreamCache, AssetChecksumGenerator assetChecksumGenerator, ResponseCustomizer responseCustomizer) { this.lastModified = lastModified; this.description = description; @@ -57,7 +60,7 @@ public class StreamableResourceImpl implements StreamableResource return compression; } - public String getContentType() + public ContentType getContentType() { return contentType; } @@ -124,7 +127,7 @@ public class StreamableResourceImpl implements StreamableResource } @Override - public StreamableResource withContentType(String newContentType) + public StreamableResource withContentType(ContentType newContentType) { return new StreamableResourceImpl(description, newContentType, compression, lastModified, bytestreamCache, assetChecksumGenerator, responseCustomizer); } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceSourceImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceSourceImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceSourceImpl.java index 1c4a67a..37cfd2d 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceSourceImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/StreamableResourceSourceImpl.java @@ -12,6 +12,7 @@ package org.apache.tapestry5.internal.services.assets; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.internal.TapestryInternalUtils; import org.apache.tapestry5.ioc.Resource; import org.apache.tapestry5.ioc.internal.util.CollectionFactory; @@ -46,7 +47,7 @@ public class StreamableResourceSourceImpl implements StreamableResourceSource this.checksumGenerator = checksumGenerator; } - public Set<String> fileExtensionsForContentType(String contentType) + public Set<String> fileExtensionsForContentType(ContentType contentType) { Set<String> result = CollectionFactory.newSet(); @@ -86,9 +87,11 @@ public class StreamableResourceSourceImpl implements StreamableResourceSource transformed.close(); - String contentType = rt == null ? contentTypeAnalyzer.getContentType(baseResource) : rt.getTransformedContentType(); + ContentType contentType = rt == null + ? new ContentType(contentTypeAnalyzer.getContentType(baseResource)) + : rt.getTransformedContentType(); - boolean compressable = compressionAnalyzer.isCompressable(contentType); + boolean compressable = compressionAnalyzer.isCompressable(contentType.getMimeType()); long lastModified = resourceChangeTracker.trackResource(baseResource); http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/UTF8ForTextAssets.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/UTF8ForTextAssets.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/UTF8ForTextAssets.java index 3bf3413..6b315bd 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/UTF8ForTextAssets.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/assets/UTF8ForTextAssets.java @@ -12,6 +12,7 @@ package org.apache.tapestry5.internal.services.assets; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.ioc.Resource; import org.apache.tapestry5.services.assets.ResourceDependencies; import org.apache.tapestry5.services.assets.StreamableResource; @@ -33,17 +34,18 @@ public class UTF8ForTextAssets extends DelegatingSRS super(delegate); } - @Override public StreamableResource getStreamableResource(Resource baseResource, StreamableResourceProcessing processing, ResourceDependencies dependencies) throws IOException { StreamableResource resource = delegate.getStreamableResource(baseResource, processing, dependencies); - if (resource.getContentType().startsWith("text/") - && !resource.getContentType().contains(";") + ContentType contentType = resource.getContentType(); + + if (contentType.getBaseType().equals("text") + && ! contentType.hasParameters() && processing != StreamableResourceProcessing.FOR_AGGREGATION) { - return resource.withContentType(resource.getContentType() + ";charset=utf-8"); + return resource.withContentType(contentType.withCharset("utf-8")); } return resource; http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java index cb8e886..21de19b 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/ModuleManagerImpl.java @@ -1,5 +1,3 @@ -// Copyright 2012, 2013 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -16,6 +14,7 @@ package org.apache.tapestry5.internal.services.javascript; import org.apache.tapestry5.SymbolConstants; import org.apache.tapestry5.dom.Element; +import org.apache.tapestry5.internal.InternalConstants; import org.apache.tapestry5.internal.services.assets.ResourceChangeTracker; import org.apache.tapestry5.ioc.Messages; import org.apache.tapestry5.ioc.Resource; @@ -82,7 +81,7 @@ public class ModuleManagerImpl implements ModuleManager classpathRoot = assetSource.resourceForPath(""); extensions = CollectionFactory.newSet("js"); - extensions.addAll(streamableResourceSource.fileExtensionsForContentType("text/javascript")); + extensions.addAll(streamableResourceSource.fileExtensionsForContentType(InternalConstants.JAVASCRIPT_CONTENT_TYPE)); baseConfig = buildBaseConfig(configuration, !productionMode); } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/test/PageTesterModule.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/test/PageTesterModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/test/PageTesterModule.java index a3c8e54..f604c05 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/test/PageTesterModule.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/test/PageTesterModule.java @@ -1,5 +1,3 @@ -// Copyright 2007-2013 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -14,6 +12,7 @@ package org.apache.tapestry5.internal.test; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.internal.services.CookieSink; import org.apache.tapestry5.internal.services.CookieSource; import org.apache.tapestry5.ioc.MappedConfiguration; @@ -66,9 +65,9 @@ public class PageTesterModule // on. configuration.add(ResponseCompressionAnalyzer.class, new ResponseCompressionAnalyzer() { - public boolean isGZipEnabled(String contentType) + public boolean isGZipEnabled(ContentType contentType) { - return locator.getObject(CompressionAnalyzer.class, null).isCompressable(contentType); + return locator.getObject(CompressionAnalyzer.class, null).isCompressable(contentType.getMimeType()); } public boolean isGZipSupported() http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/services/ResponseCompressionAnalyzer.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/ResponseCompressionAnalyzer.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/ResponseCompressionAnalyzer.java index d9a61b2..3518f20 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/ResponseCompressionAnalyzer.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/ResponseCompressionAnalyzer.java @@ -1,5 +1,3 @@ -// Copyright 2009-2013 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -14,6 +12,7 @@ package org.apache.tapestry5.services; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.services.assets.CompressionAnalyzer; /** @@ -41,5 +40,5 @@ public interface ResponseCompressionAnalyzer * @return true if the content can be compressed for the current request * @since 5.4 */ - boolean isGZipEnabled(String contentType); + boolean isGZipEnabled(ContentType contentType); } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/ResourceTransformer.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/ResourceTransformer.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/ResourceTransformer.java index 457bd47..686fa58 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/ResourceTransformer.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/ResourceTransformer.java @@ -1,5 +1,3 @@ -// Copyright 2011, 2012 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -14,6 +12,7 @@ package org.apache.tapestry5.services.assets; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.ioc.Resource; import java.io.IOException; @@ -35,7 +34,7 @@ public interface ResourceTransformer * * @since 5.4 */ - String getTransformedContentType(); + ContentType getTransformedContentType(); /** * Read the source input stream and provide a new input stream of the transformed content. http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/StreamableResource.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/StreamableResource.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/StreamableResource.java index 9f52fd6..255f35a 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/StreamableResource.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/StreamableResource.java @@ -12,7 +12,9 @@ package org.apache.tapestry5.services.assets; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.ioc.Resource; +import org.apache.tapestry5.ioc.annotations.IncompatibleChange; import java.io.IOException; import java.io.InputStream; @@ -40,9 +42,10 @@ public interface StreamableResource CompressionStatus getCompression(); /** - * Returns the MIME content type, for example, "image/jpeg". + * Returns the resource's content type. */ - String getContentType(); + @IncompatibleChange(release = "5.4", details = "Changed from type String to ContentType") + ContentType getContentType(); /** * The size, in bytes, of the underlying bytestream. @@ -102,5 +105,5 @@ public interface StreamableResource * @param newContentType * @since 5.4 */ - StreamableResource withContentType(String newContentType); + StreamableResource withContentType(ContentType newContentType); } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/StreamableResourceSource.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/StreamableResourceSource.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/StreamableResourceSource.java index 4a35499..70974aa 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/StreamableResourceSource.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/assets/StreamableResourceSource.java @@ -14,6 +14,7 @@ package org.apache.tapestry5.services.assets; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.ioc.Resource; import org.apache.tapestry5.ioc.annotations.UsesMappedConfiguration; @@ -38,12 +39,12 @@ public interface StreamableResourceSource * based for a file with that extension. * * @param contentType - * to search for - * @return set of file extension, possibly empty, in no particular order. These are the bare extensions, i.e. - * "js", "coffee". + * to search for (just a MIME type, such as "text/javascript") + * @return set of file extension, possibly empty, in no particular order. These are the bare extensions, e.g., + * "js", "coffee". * @since 5.4 */ - Set<String> fileExtensionsForContentType(String contentType); + Set<String> fileExtensionsForContentType(ContentType contentType); /** * Converts a Resource (which must be non-null and exist) into a streamable resource, along with http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/main/java/org/apache/tapestry5/util/TextStreamResponse.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/util/TextStreamResponse.java b/tapestry-core/src/main/java/org/apache/tapestry5/util/TextStreamResponse.java index 75d22a7..d3ad2f1 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/util/TextStreamResponse.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/util/TextStreamResponse.java @@ -1,5 +1,3 @@ -// Copyright 2007, 2008, 2010 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -49,7 +47,7 @@ public class TextStreamResponse implements StreamResponse */ public TextStreamResponse(String contentType, String charset, String text) { - this(new ContentType(contentType, charset), text); + this(new ContentType(contentType).withCharset(charset), text); } public TextStreamResponse(ContentType contentType, String text) http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-core/src/test/java/org/apache/tapestry5/root/ContentTypeTest.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/root/ContentTypeTest.java b/tapestry-core/src/test/java/org/apache/tapestry5/root/ContentTypeTest.java index 2e16fc9..b469efc 100644 --- a/tapestry-core/src/test/java/org/apache/tapestry5/root/ContentTypeTest.java +++ b/tapestry-core/src/test/java/org/apache/tapestry5/root/ContentTypeTest.java @@ -1,5 +1,3 @@ -// Copyright 2007, 2008 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -15,12 +13,13 @@ package org.apache.tapestry5.root; import org.apache.tapestry5.ContentType; -import org.testng.Assert; +import org.apache.tapestry5.ioc.test.TestBase; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.util.List; -public class ContentTypeTest extends Assert +public class ContentTypeTest extends TestBase { @Test public void simple_equals() @@ -73,10 +72,41 @@ public class ContentTypeTest extends Assert assertEquals(contentType.getCharset(), "utf-8"); + assertTrue(contentType.hasParameters()); + String nonexistant = contentType.getParameter("nonexistant"); + assertTrue(nonexistant == null); } + @DataProvider + public Object[][] invalid_content_type_strings_data() + { + return new Object[][]{ + {""}, + {"foo/"}, + {"foo/bar;"}, + {"foo/bar;baz"}, + {"foo/bar;baz="}, + {"foo/bar;baz=biff;"} + }; + } + + @Test(dataProvider = "invalid_content_type_strings_data") + public void invalid_content_type_strings(String input) + { + try + { + new ContentType(input); + + unreachable(); + } catch (IllegalArgumentException ex) + { + + } + + } + @Test public void parse_without_parameters() throws Exception { @@ -89,40 +119,39 @@ public class ContentTypeTest extends Assert assertEquals(contentType.getMimeType(), "text/html"); assertTrue(contentType.getParameterNames().isEmpty()); + + assertFalse(contentType.hasParameters()); } @Test public void unparse_with_parameters() throws Exception { - ContentType contentType = new ContentType(); - - contentType.setBaseType("text"); - contentType.setSubType("html"); - contentType.setParameter("charset", "utf-8"); + ContentType contentType = new ContentType("text/html").withCharset("utf-8"); - assertEquals(contentType.unparse(), "text/html;charset=utf-8"); + assertEquals(contentType.toString(), "text/html;charset=utf-8"); } @Test public void unparse_no_parameters() throws Exception { - ContentType contentType = new ContentType(); - - contentType.setBaseType("text"); - contentType.setSubType("html"); + ContentType contentType = new ContentType("text/html"); - assertEquals(contentType.unparse(), "text/html"); + assertEquals(contentType.toString(), "text/html"); } @Test - public void to_string_is_unparse() + public void add_charset() throws Exception { - ContentType contentType = new ContentType(); + ContentType base = new ContentType("text/html"); + + ContentType charset = base.withCharset("utf-8"); + + assertTrue(charset.hasParameters()); - contentType.setBaseType("text"); - contentType.setSubType("html"); - contentType.setParameter("charset", "utf-8"); + assertNotSame(base, charset); + assertNotEquals(base, charset); - assertEquals(contentType.toString(), contentType.unparse()); + assertEquals(base.toString(), "text/html"); + assertEquals(charset.toString(), "text/html;charset=utf-8"); } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/CoffeeScriptCompiler.java ---------------------------------------------------------------------- diff --git a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/CoffeeScriptCompiler.java b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/CoffeeScriptCompiler.java index 1f11579..cdbf504 100644 --- a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/CoffeeScriptCompiler.java +++ b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/CoffeeScriptCompiler.java @@ -1,5 +1,3 @@ -// Copyright 2013-2014 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -15,7 +13,9 @@ package org.apache.tapestry5.internal.webresources; import org.apache.commons.io.IOUtils; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.annotations.Path; +import org.apache.tapestry5.internal.InternalConstants; import org.apache.tapestry5.ioc.OperationTracker; import org.apache.tapestry5.ioc.Resource; import org.apache.tapestry5.ioc.internal.util.CollectionFactory; @@ -36,9 +36,9 @@ public class CoffeeScriptCompiler implements ResourceTransformer private final RhinoExecutorPool executorPool; @Override - public String getTransformedContentType() + public ContentType getTransformedContentType() { - return "text/javascript"; + return InternalConstants.JAVASCRIPT_CONTENT_TYPE; } public CoffeeScriptCompiler(@Path("classpath:org/apache/tapestry5/webresources/internal/coffee-script.js") @@ -64,7 +64,7 @@ public class CoffeeScriptCompiler implements ResourceTransformer } - private String getString(NativeObject object, String key) + private static String getString(NativeObject object, String key) { return object.get(key).toString(); } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/DelegatingResourceTransformer.java ---------------------------------------------------------------------- diff --git a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/DelegatingResourceTransformer.java b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/DelegatingResourceTransformer.java new file mode 100644 index 0000000..75cccbd --- /dev/null +++ b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/DelegatingResourceTransformer.java @@ -0,0 +1,32 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package org.apache.tapestry5.internal.webresources; + +import org.apache.tapestry5.ContentType; +import org.apache.tapestry5.services.assets.ResourceTransformer; + +public abstract class DelegatingResourceTransformer implements ResourceTransformer +{ + protected final ResourceTransformer delegate; + + protected DelegatingResourceTransformer(ResourceTransformer delegate) + { + this.delegate = delegate; + } + + @Override + public ContentType getTransformedContentType() + { + return delegate.getTransformedContentType(); + } +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/LessResourceTransformer.java ---------------------------------------------------------------------- diff --git a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/LessResourceTransformer.java b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/LessResourceTransformer.java index ebaf35d..e60568a 100644 --- a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/LessResourceTransformer.java +++ b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/LessResourceTransformer.java @@ -1,5 +1,3 @@ -// Copyright 2013-2014 The Apache Software Foundation -// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -18,6 +16,7 @@ import com.github.sommeri.less4j.Less4jException; import com.github.sommeri.less4j.LessCompiler; import com.github.sommeri.less4j.LessSource; import com.github.sommeri.less4j.core.DefaultLessCompiler; +import org.apache.tapestry5.ContentType; import org.apache.tapestry5.internal.services.assets.BytestreamCache; import org.apache.tapestry5.ioc.Resource; import org.apache.tapestry5.services.assets.ResourceDependencies; @@ -33,12 +32,14 @@ import java.io.UnsupportedEncodingException; */ public class LessResourceTransformer implements ResourceTransformer { + private static final ContentType CSS = new ContentType("text/css"); + private final LessCompiler compiler = new DefaultLessCompiler(); @Override - public String getTransformedContentType() + public ContentType getTransformedContentType() { - return "text/css"; + return CSS; } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/85622bc3/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/ResourceTransformerFactoryImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/ResourceTransformerFactoryImpl.java b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/ResourceTransformerFactoryImpl.java index 904fa54..4731004 100644 --- a/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/ResourceTransformerFactoryImpl.java +++ b/tapestry-webresources/src/main/java/org/apache/tapestry5/internal/webresources/ResourceTransformerFactoryImpl.java @@ -126,17 +126,11 @@ public class ResourceTransformerFactoryImpl implements ResourceTransformerFactor } } - private ResourceTransformer wrapWithTracking(final String sourceName, final String targetName, final ResourceTransformer core) + private ResourceTransformer wrapWithTracking(final String sourceName, final String targetName, ResourceTransformer core) { - return new ResourceTransformer() + return new DelegatingResourceTransformer(core) { @Override - public String getTransformedContentType() - { - return core.getTransformedContentType(); - } - - @Override public InputStream transform(final Resource source, final ResourceDependencies dependencies) throws IOException { final String description = String.format("Compiling %s from %s to %s", source, sourceName, targetName); @@ -146,29 +140,23 @@ public class ResourceTransformerFactoryImpl implements ResourceTransformerFactor @Override public InputStream perform() throws IOException { - return core.transform(source, dependencies); + return delegate.transform(source, dependencies); } }); } }; } - private ResourceTransformer wrapWithTiming(final String targetName, final ResourceTransformer coreCompiler) + private ResourceTransformer wrapWithTiming(final String targetName, ResourceTransformer coreCompiler) { - return new ResourceTransformer() + return new DelegatingResourceTransformer(coreCompiler) { @Override - public String getTransformedContentType() - { - return coreCompiler.getTransformedContentType(); - } - - @Override public InputStream transform(final Resource source, final ResourceDependencies dependencies) throws IOException { final long startTime = System.nanoTime(); - InputStream result = coreCompiler.transform(source, dependencies); + InputStream result = delegate.transform(source, dependencies); final long elapsedTime = System.nanoTime() - startTime; @@ -188,19 +176,13 @@ public class ResourceTransformerFactoryImpl implements ResourceTransformerFactor * somewhat primitive: a change to *any* resource in a given domain results in the cache of all of those resources * being discarded. */ - private ResourceTransformer wrapWithInMemoryCaching(final ResourceTransformer core, final String targetName) + private ResourceTransformer wrapWithInMemoryCaching( ResourceTransformer core, final String targetName) { - return new ResourceTransformer() + return new DelegatingResourceTransformer(core) { final Map<Resource, Compiled> cache = CollectionFactory.newConcurrentMap(); @Override - public String getTransformedContentType() - { - return core.getTransformedContentType(); - } - - @Override public InputStream transform(Resource source, ResourceDependencies dependencies) throws IOException { Compiled compiled = cache.get(source); @@ -215,7 +197,7 @@ public class ResourceTransformerFactoryImpl implements ResourceTransformerFactor compiled = new Compiled(source); - InputStream is = core.transform(source, new ResourceDependenciesSplitter(dependencies, compiled)); + InputStream is = delegate.transform(source, new ResourceDependenciesSplitter(dependencies, compiled)); compiled.store(is); @@ -228,17 +210,11 @@ public class ResourceTransformerFactoryImpl implements ResourceTransformerFactor }; } - private ResourceTransformer wrapWithFileSystemCaching(final ResourceTransformer core, final String targetName) + private ResourceTransformer wrapWithFileSystemCaching( ResourceTransformer core, final String targetName) { - return new ResourceTransformer() + return new DelegatingResourceTransformer(core) { @Override - public String getTransformedContentType() - { - return core.getTransformedContentType(); - } - - @Override public InputStream transform(Resource source, ResourceDependencies dependencies) throws IOException { long checksum = ResourceTransformUtils.toChecksum(source); @@ -254,7 +230,7 @@ public class ResourceTransformerFactoryImpl implements ResourceTransformerFactor return new BufferedInputStream(new FileInputStream(cacheFile)); } - InputStream compiled = core.transform(source, dependencies); + InputStream compiled = delegate.transform(source, dependencies); // We need the InputStream twice; once to return, and once to write out to the cache file for later.
