package com.xoetrope.service;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Vector;
import java.util.zip.Adler32;
import java.util.zip.CheckedInputStream;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import net.xoetrope.debug.DebugLogger;
import net.xoetrope.optional.service.ServiceProxy;
import net.xoetrope.optional.service.ServiceProxyException;
import com.xoetrope.carousel.build.BuildProperties;
import java.util.Hashtable;
import net.xoetrope.optional.service.ServiceContext;
import net.xoetrope.optional.service.ServiceProxyArgs;
/**
* Compresses the output data in a zip stream
*
* <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
* the GNU Public License (GPL), please see license.txt for more details. If
* you make commercial use of this software you must purchase a commercial
* license from Xoetrope.</p>
* <p> $Revision: 1.9 $</p>
*/
public class ZipDecoderService extends ServiceProxy
{
public ZipDecoderService()
{
status = OK;
}
/**
* Deompresses the call, its arguments using the ZLib zip algorithm. The
* response is compressed. The call is then forwarded to the
* next service proxy in the chain.
* @param method the method name to be invoked
* @param context the context of the service call
* @return the response or result of the call
* @throws ServiceProxyException
*/
public Object call( String method, ServiceContext context ) throws ServiceProxyException
{
try {
status = STARTED;
//int numArgs = args.getNumArgs();
ServiceProxyArgs args = context.getArgs();
// Decompress the output.
if ( BuildProperties.DEBUG ) {
if ( args.getPassParam( "ZipStream" ) == null ) {
DebugLogger.logError( "Invalid ZipDecoderService argument" );
throw new ServiceProxyException( "Invalid ZipDecoderService argument" );
}
}
ByteArrayInputStream bis = new ByteArrayInputStream( org.apache.catalina.util.Base64.decode( ((String)args.getPassParam( "ZipStream" )).getBytes() ));
CheckedInputStream cis = new CheckedInputStream( bis, new Adler32() );
ZipInputStream zis = new ZipInputStream( cis );
Vector zipArgNames = new Vector();
Vector zipArgValues = new Vector();
final int BUFFER_SIZE = 2048;
int count;
byte[] buf = new byte[ BUFFER_SIZE ];
ZipEntry ze;
while ( ( ze = zis.getNextEntry() ) != null ) {
zipArgNames.addElement( ze.getName() );
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ( ( zis.available() > 0 ) && ( ( count = zis.read( buf, 0, BUFFER_SIZE ) ) != -1 ) )
bos.write( buf, 0, count );
zipArgValues.addElement( new String( bos.toByteArray() ) );
}
// Call the next service proxy
ServiceContext callContext = new ServiceContext();
Hashtable passArgs = callContext.getPassArgs();
passArgs.clear();
int numDecodedArgs = zipArgNames.size();
String decodedArgNames[] = new String[ numDecodedArgs ];
for ( int k = 0; k < numDecodedArgs; k++ )
passArgs.put( (String)zipArgNames.elementAt( k ), zipArgValues.elementAt( k ));
Object status = nextProxy.call( method, callContext );
Object result = callContext.getReturnArgs().get( ServiceProxy.RETURN_VALUE );
ByteArrayOutputStream bos = new ByteArrayOutputStream();
CheckedOutputStream cos = new CheckedOutputStream( bos, new Adler32() );
ZipOutputStream zos = new ZipOutputStream( cos );
// Create a new entry and output
if ( result != null ) {
ZipEntry zeOut = new ZipEntry( "ZipStream" );
zos.putNextEntry( zeOut );
zos.write( result.toString().getBytes());
zeOut.setCrc( cos.getChecksum().getValue() );
}
zos.close();
status = COMPLETE;
context.setReturnValue( new String( org.apache.catalina.util.Base64.encode( bos.toByteArray())));
return status;
}
catch ( IOException ioex ) {
status = FAILED;
if ( BuildProperties.DEBUG )
ioex.printStackTrace();
}
catch ( ServiceProxyException ex ) {
status = FAILED;
throw ( ex );
}
return null;
}
}
|