001// Copyright 2011 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.internal.services.assets; 016 017import org.apache.tapestry5.ioc.Resource; 018import org.apache.tapestry5.services.assets.*; 019 020import java.io.BufferedOutputStream; 021import java.io.ByteArrayOutputStream; 022import java.io.IOException; 023import java.util.zip.GZIPOutputStream; 024 025public class SRSCompressingInterceptor implements StreamableResourceSource 026{ 027 private final int compressionCutoff; 028 029 private final StreamableResourceSource delegate; 030 031 public SRSCompressingInterceptor(int compressionCutoff, StreamableResourceSource delegate) 032 { 033 this.compressionCutoff = compressionCutoff; 034 this.delegate = delegate; 035 } 036 037 public StreamableResource getStreamableResource(Resource baseResource, StreamableResourceProcessing processing, ResourceDependencies dependencies) 038 throws IOException 039 { 040 StreamableResource streamable = delegate.getStreamableResource(baseResource, processing, dependencies); 041 042 return processing == StreamableResourceProcessing.COMPRESSION_ENABLED ? compress(streamable) : streamable; 043 } 044 045 private StreamableResource compress(StreamableResource uncompressed) throws IOException 046 { 047 if (uncompressed.getCompression() != CompressionStatus.COMPRESSABLE) 048 { 049 return uncompressed; 050 } 051 052 int size = uncompressed.getSize(); 053 054 // Because of GZIP overhead, streams below a certain point actually get larger when compressed so 055 // we don't even try. 056 057 if (size < compressionCutoff) 058 { 059 return uncompressed; 060 } 061 062 ByteArrayOutputStream bos = new ByteArrayOutputStream(size); 063 064 GZIPOutputStream gos = new GZIPOutputStream(bos); 065 BufferedOutputStream buffered = new BufferedOutputStream(gos); 066 067 uncompressed.streamTo(buffered); 068 069 buffered.close(); 070 071 BytestreamCache cache = new BytestreamCache(bos); 072 073 return new StreamableResourceImpl(uncompressed.getDescription(), 074 uncompressed.getContentType(), CompressionStatus.COMPRESSED, 075 uncompressed.getLastModified(), cache); 076 } 077}