package center.task.prm.alg;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import ru.vassaev.core.base.Null;
import ru.vassaev.core.exception.SysRuntimeException;
import ru.vassaev.core.thread.Process;
import ru.vassaev.core.io.OutputByteBuffer;
import ru.vassaev.core.types.TimeList;
import ru.vassaev.core.util.Bytes;
import ru.vassaev.core.util.Strings;
import ru.vassaev.core.xml.XMLFileWaiter;
import center.task.CalculateException;
import center.task.Context;
import center.task.Record;
/**
* Параметр архивирует или разархивирует данные
* @author Vassaev A.V.
* @version 1.0 01/07/2012
*
*/
public final class ArchiveLinkParam extends LinkParam {
private int sizeBuffer;
private int sizeCache;
private enum Type {ZIP, UNZIP}
private Type tp;
public ArchiveLinkParam(center.task.prm.Type tp, String owner, Element e) {
super(tp, owner, e);
sizeBuffer = Strings.parseIntegerNvl(e.getAttribute("size_buffer"), 8000);
if (sizeBuffer <= 0)
sizeBuffer = 8000;
sizeCache = Strings.parseIntegerNvl(e.getAttribute("size_cache"), 8000);
if (sizeCache <= 0)
sizeCache = 8000;
Type ltp = Type.valueOf(e.getAttribute("direction"));
if (ltp == null)
ltp = Type.ZIP;
this.tp = ltp;
}
private Object zip(Object v) throws IOException {
if (v instanceof Document) {
Document d = (Document)v;
Element e = d.getDocumentElement();
OutputByteBuffer res = Process.getByteBuffer(sizeCache);
OutputStream os = new java.util.zip.GZIPOutputStream(res, sizeBuffer);
XMLFileWaiter.putStream(e, os, "utf-8");
os.close();
return res;
} else if (v instanceof Element) {
Element e = (Element)v;
OutputByteBuffer res = Process.getByteBuffer(sizeCache);
OutputStream os = new java.util.zip.GZIPOutputStream(res, sizeBuffer);
XMLFileWaiter.putStream(e, os, "utf-8");
os.close();
return res;
} else if (v instanceof InputStream) {
InputStream is = (InputStream) v;
OutputByteBuffer res = Process.getByteBuffer(sizeCache);
GZIPOutputStream os = new GZIPOutputStream(res, sizeBuffer);
Bytes.copyStream(is, os, res.getBufferSize());
os.close();
return res;
} else if (v instanceof OutputByteBuffer) {
InputStream is = ((OutputByteBuffer) v).getIS();
OutputByteBuffer res = Process.getByteBuffer(sizeCache);
GZIPOutputStream os = new GZIPOutputStream(res, sizeBuffer);
Bytes.copyStream(is, os, res.getBufferSize());
os.close();
return res;
} else if (v instanceof String || v instanceof StringBuffer) {
String r = v.toString();
ByteArrayInputStream is = new ByteArrayInputStream(r.getBytes("utf-8"));
OutputByteBuffer res = Process.getByteBuffer(sizeCache);
GZIPOutputStream os = new GZIPOutputStream(res, sizeBuffer);
Bytes.copyStream(is, os, res.getBufferSize());
os.close();
return res;
} else if (v instanceof File) {
File r = (File)v;
FileInputStream is = new FileInputStream(r.getCanonicalPath());
OutputByteBuffer res = null;
try {
res = Process.getByteBuffer(sizeCache);
GZIPOutputStream os = new GZIPOutputStream(res, sizeBuffer);
Bytes.copyStream(is, os, res.getBufferSize());
os.close();
} finally {
is.close();
}
return res;
} else if (v instanceof Record) {
String r = Strings.getString(((Record) v).value.get(0));
if (r == null)
return null;
ByteArrayInputStream is = new ByteArrayInputStream(r.getBytes("utf-8"));
OutputByteBuffer res = Process.getByteBuffer(sizeCache);
GZIPOutputStream os = new GZIPOutputStream(res, sizeBuffer);
Bytes.copyStream(is, os, res.getBufferSize());
os.close();
return res;
} else
throw new SysRuntimeException("The source's type isn't supported:"
+ v.getClass().getCanonicalName());
}
private Object unzip(Object v) throws IOException, ZipException {
if (v instanceof InputStream) {
InputStream is = new GZIPInputStream((InputStream) v, sizeBuffer);
OutputByteBuffer res = Process.getByteBuffer(sizeCache);
Bytes.copyStream(is, res, res.getBufferSize());
res.close();
is.close();
return res;
} else if (v instanceof File) {
FileInputStream fis = new FileInputStream(((File) v).getCanonicalPath());
try {
InputStream is = new GZIPInputStream(fis, sizeBuffer);
OutputByteBuffer res = Process.getByteBuffer(sizeCache);
Bytes.copyStream(is, res, res.getBufferSize());
res.close();
is.close();
return res;
} finally {
fis.close();
}
} else if (v instanceof OutputByteBuffer) {
InputStream is = new GZIPInputStream(((OutputByteBuffer) v).getIS(), sizeBuffer);
OutputByteBuffer res = Process.getByteBuffer(sizeCache);
Bytes.copyStream(is, res, res.getBufferSize());
res.close();
is.close();
return res;
} else
throw new SysRuntimeException("The source's type isn't supported:"
+ v.getClass().getCanonicalName());
}
public Object calculate(TimeList tl, Context cntx) throws CalculateException {
try {
tl.addPointTime(TimeList.Type.START);
Object v = super.calculate(tl, cntx);
if (Null.NULL.equals(v))
return null;
if (Type.ZIP.equals(tp))
return zip(v);
return unzip(v);
} catch(IOException e) {
throw new CalculateException(owner, e);
} finally {
tl.addPointTime(TimeList.Type.END);
}
}
}