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 015 package org.apache.tapestry5.internal.services.assets; 016 017 import org.apache.tapestry5.ioc.Resource; 018 import org.apache.tapestry5.services.assets.*; 019 020 import java.io.BufferedOutputStream; 021 import java.io.ByteArrayOutputStream; 022 import java.io.IOException; 023 import java.util.zip.GZIPOutputStream; 024 025 public 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 }