at.spardat.xma.session.Transform Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* s IT Solutions AT Spardat GmbH - initial API and implementation
*******************************************************************************/
/*
* @(#) $Id: Transform.java 2089 2007-11-28 13:56:13Z s3460 $
*
*
*
*
*
*/
package at.spardat.xma.session;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import at.spardat.enterprise.exc.SysException;
import at.spardat.xma.boot.transform.HashChecksum;
/**
*
* e.g. XMA-Transform: hash,xdelta,gzip
* Unrecognized header fields [...] MUST be forwarded by transparent proxies.
* @author s2877
* @since 1.4.0
*/
public class Transform {
public static final String Header = "XMA-Transform";
public static final String hashProtection = "hash";
public static final String gzipCompression = "gzip";
// public static final String deltaDownload = "xdelta";
String transformations;
public String getTransformations() {
return transformations;
}
public byte[] generateHash(byte[] buffer) {
try {
byte[] hash = ("\n"+HashChecksum.calcCheckSum(buffer)).getBytes("US-ASCII");
byte[] result = new byte[hash.length+buffer.length];
System.arraycopy(buffer,0,result,0,buffer.length);
System.arraycopy(hash,0,result,buffer.length,hash.length);
transformations = transformations!=null?transformations+','+hashProtection:hashProtection;
return result;
} catch (UnsupportedEncodingException exc) {
throw new SysException(exc);
}
}
public static byte[] checkHash(byte[] buffer) {
try {
if(buffer.length>32) {
String hash = new String(buffer,buffer.length-32,32,"US-ASCII");
if(buffer[buffer.length-33]=='\n') {
byte[] result = new byte[buffer.length-33];
System.arraycopy(buffer,0,result,0,result.length);
String calculatedHash = HashChecksum.calcCheckSum(result);
if(calculatedHash.equals(hash)) {
return result;
}
}
}
throw new SysException("integrity violation");
} catch (UnsupportedEncodingException exc) {
throw new SysException(exc);
}
}
/**
* GZip compresses the input buffer and returns the compressed result.
*/
public byte[] compress(byte[] buffer) {
if (buffer == null) throw new IllegalArgumentException();
transformations = transformations!=null?transformations+','+gzipCompression:gzipCompression;
GZIPOutputStream gZipOut = null;
ByteArrayOutputStream bArrOut = new ByteArrayOutputStream (buffer.length/2);
try {
gZipOut = new GZIPOutputStream (bArrOut);
gZipOut.write (buffer, 0, buffer.length);
gZipOut.close();
} catch (IOException x) {
throw new SysException (x);
}
return bArrOut.toByteArray();
}
/**
* Decompresses a byte[] previously compressed with compress. I.e., for every
* conceivable byte[] x the following must hold: (x isSameByteArray decompress(compress(x)))
*/
public static byte[] decompress (byte[] buffer) {
if (buffer == null) throw new IllegalArgumentException();
GZIPInputStream gZipIn = null;
ByteArrayInputStream bArrIn = new ByteArrayInputStream (buffer);
ByteArrayOutputStream bArrOut = new ByteArrayOutputStream (buffer.length);
try {
gZipIn = new GZIPInputStream (bArrIn);
byte[] buf = new byte[1024];
int read = 0;
while ((read = gZipIn.read(buf)) > 0) {
bArrOut.write (buf, 0, read);
}
gZipIn.close();
bArrOut.close();
} catch (IOException x) {
throw new SysException (x);
}
return bArrOut.toByteArray();
}
public static byte[] decode(String transformations,byte[] buffer) {
byte[] result = buffer;
List trans = new ArrayList();
for(StringTokenizer tok=new StringTokenizer(transformations,",");tok.hasMoreTokens();) {
trans.add(tok.nextToken());
}
for(int i=trans.size()-1;i>=0;i--) {
String operation = (String) trans.get(i);
if(hashProtection.equals(operation)) {
result = checkHash(result);
} else if (gzipCompression.equals(operation)) {
result = decompress(result);
}
}
return result;
}
}