package com.ximple.eofms.jobs;
|
|
import java.io.File;
|
import java.io.FileOutputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.nio.ByteBuffer;
|
import java.nio.channels.FileChannel;
|
import java.sql.Connection;
|
import java.sql.ResultSet;
|
import java.sql.SQLException;
|
import java.sql.Statement;
|
import java.sql.Types;
|
import java.util.ArrayList;
|
import java.util.ListIterator;
|
|
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.LogFactory;
|
|
import com.vividsolutions.jts.util.Assert;
|
|
import oracle.sql.BLOB;
|
|
import com.ximple.eofms.util.PrintfFormat;
|
import com.ximple.io.dgn7.ArcElement;
|
import com.ximple.io.dgn7.ComplexChainElement;
|
import com.ximple.io.dgn7.ComplexShapeElement;
|
import com.ximple.io.dgn7.Element;
|
import com.ximple.io.dgn7.EllipseElement;
|
import com.ximple.io.dgn7.LineElement;
|
import com.ximple.io.dgn7.LineStringElement;
|
import com.ximple.io.dgn7.ShapeElement;
|
import com.ximple.io.dgn7.TextElement;
|
import com.ximple.io.dgn7.TextNodeElement;
|
import com.ximple.io.dgn7.IElementHandler;
|
import com.ximple.io.dgn7.Dgn7fileException;
|
|
public class OracleElementLogger
|
{
|
static Log logger = LogFactory.getLog(OracleElementLogger.class);
|
private static final String DEFAULT_ELMOUTPATH = "elmout";
|
private static final String TAB_IGDSSEED = "SD$IGDSSET_SEED";
|
|
private Connection connection;
|
private String dataOut = null;
|
private String dataPath;
|
private String currentSchema;
|
private boolean schemaChanged;
|
private FileOutputStream fos = null;
|
private FileChannel fch = null;
|
private int logCount = 0;
|
private int elmCount = 0;
|
private int maxElmCount = 3000;
|
private boolean useElementCount = true;
|
private ArrayList<byte[]> dgnFileHeader = null;
|
private String elmOutPath;
|
|
public OracleElementLogger(Connection connection)
|
{
|
this.connection = connection;
|
elmOutPath = DEFAULT_ELMOUTPATH;
|
}
|
|
public OracleElementLogger(Connection connection, String elmOutPath)
|
{
|
this.connection = connection;
|
this.elmOutPath = elmOutPath;
|
}
|
|
public String getDataOutPath()
|
{
|
if (dataOut == null)
|
{
|
File outPath = new File(getDataPath(), elmOutPath);
|
if (!outPath.exists())
|
{
|
outPath.mkdir();
|
} else if (!outPath.isDirectory())
|
{
|
outPath.mkdir();
|
}
|
dataOut = outPath.toString();
|
}
|
return dataOut;
|
}
|
|
public String getDataPath()
|
{
|
return dataPath;
|
}
|
|
public void setDataPath(String dataPath)
|
{
|
this.dataPath = dataPath;
|
}
|
|
public void logElement(Element element, String currentSchema)
|
{
|
if ((this.currentSchema == null) ||
|
(!this.currentSchema.equalsIgnoreCase(currentSchema)))
|
{
|
schemaChanged = true;
|
this.currentSchema = currentSchema;
|
try
|
{
|
createNewStream();
|
} catch (IOException e)
|
{
|
logger.warn(e.getMessage(), e);
|
return;
|
} catch (SQLException e)
|
{
|
logger.warn(e.getMessage(), e);
|
return;
|
}
|
} else
|
{
|
if (fch == null)
|
{
|
try
|
{
|
createNewStream();
|
} catch (IOException e)
|
{
|
logger.warn(e.getMessage(), e);
|
return;
|
} catch (SQLException e)
|
{
|
logger.warn(e.getMessage(), e);
|
return;
|
}
|
}
|
}
|
|
ArrayList<ByteBuffer> subBuffers = new ArrayList<ByteBuffer>();
|
if (fch != null)
|
{
|
ByteBuffer buf = null;
|
if (element instanceof LineElement)
|
{
|
int size = LineElement.ElementHandler.getInstance().getLength(element);
|
buf = ByteBuffer.allocate(size * 2);
|
LineElement.ElementHandler.getInstance().write(buf, element);
|
} else if (element instanceof ShapeElement)
|
{
|
int size = ShapeElement.ElementHandler.getInstance().getLength(element);
|
buf = ByteBuffer.allocate(size * 2);
|
ShapeElement.ElementHandler.getInstance().write(buf, element);
|
} else if (element instanceof LineStringElement)
|
{
|
int size = LineStringElement.ElementHandler.getInstance().getLength(element);
|
buf = ByteBuffer.allocate(size * 2);
|
LineStringElement.ElementHandler.getInstance().write(buf, element);
|
} else if (element instanceof ComplexChainElement)
|
{
|
int size = ComplexChainElement.ElementHandler.getInstance().getLength(element);
|
buf = ByteBuffer.allocate(size * 2);
|
ComplexChainElement.ElementHandler.getInstance().write(buf, element);
|
ComplexChainElement complexElement = (ComplexChainElement) element;
|
ListIterator it = complexElement.listIterator();
|
while (it.hasNext())
|
{
|
Element subElm = (Element) it.next();
|
try
|
{
|
IElementHandler handler = subElm.getElementType().getElementHandler();
|
size = handler.getLength(subElm);
|
ByteBuffer subBuf = ByteBuffer.allocate(size * 2);
|
handler.write(subBuf, subElm);
|
subBuffers.add(subBuf);
|
} catch (Dgn7fileException e)
|
{
|
logger.warn(e.getMessage(), e);
|
}
|
}
|
} else if (element instanceof ComplexShapeElement)
|
{
|
int size = ComplexShapeElement.ElementHandler.getInstance().getLength(element);
|
buf = ByteBuffer.allocate(size * 2);
|
ComplexShapeElement.ElementHandler.getInstance().write(buf, element);
|
ComplexShapeElement complexElement = (ComplexShapeElement) element;
|
ListIterator it = complexElement.listIterator();
|
while (it.hasNext())
|
{
|
Element subElm = (Element) it.next();
|
try
|
{
|
IElementHandler handler = subElm.getElementType().getElementHandler();
|
size = handler.getLength(subElm);
|
ByteBuffer subBuf = ByteBuffer.allocate(size * 2);
|
handler.write(subBuf, subElm);
|
subBuffers.add(subBuf);
|
} catch (Dgn7fileException e)
|
{
|
logger.warn(e.getMessage(), e);
|
}
|
}
|
} else if (element instanceof ArcElement)
|
{
|
int size = ArcElement.ElementHandler.getInstance().getLength(element);
|
buf = ByteBuffer.allocate(size * 2);
|
ArcElement.ElementHandler.getInstance().write(buf, element);
|
} else if (element instanceof EllipseElement)
|
{
|
int size = EllipseElement.ElementHandler.getInstance().getLength(element);
|
buf = ByteBuffer.allocate(size * 2);
|
EllipseElement.ElementHandler.getInstance().write(buf, element);
|
} else if (element instanceof TextElement)
|
{
|
int size = TextElement.ElementHandler.getInstance().getLength(element);
|
buf = ByteBuffer.allocate(size * 2);
|
TextElement.ElementHandler.getInstance().write(buf, element);
|
} else if (element instanceof TextNodeElement)
|
{
|
int size = TextNodeElement.ElementHandler.getInstance().getLength(element);
|
buf = ByteBuffer.allocate(size * 2);
|
TextNodeElement.ElementHandler.getInstance().write(buf, element);
|
TextNodeElement nodeElement = (TextNodeElement) element;
|
ListIterator it = nodeElement.listIterator();
|
while (it.hasNext())
|
{
|
Element subElm = (Element) it.next();
|
try
|
{
|
IElementHandler handler = subElm.getElementType().getElementHandler();
|
size = handler.getLength(subElm);
|
ByteBuffer subBuf = ByteBuffer.allocate(size * 2);
|
handler.write(subBuf, subElm);
|
subBuffers.add(subBuf);
|
} catch (Dgn7fileException e)
|
{
|
logger.warn(e.getMessage(), e);
|
}
|
}
|
}
|
|
if ((buf != null) && (fch != null))
|
{
|
try
|
{
|
buf.position(0);
|
int size = fch.write(buf);
|
if (size != buf.limit())
|
{
|
long position = fch.position();
|
logger.info("Pos:" + position);
|
}
|
} catch (IOException e)
|
{
|
logger.warn(e.getMessage(), e);
|
}
|
}
|
}
|
|
elmCount++;
|
if ((subBuffers.size() != 0) && (fch != null))
|
{
|
for (ByteBuffer buf : subBuffers)
|
{
|
try
|
{
|
buf.position(0);
|
int size = fch.write(buf);
|
if (size != buf.limit())
|
{
|
long position = fch.position();
|
logger.info("Pos:" + position);
|
}
|
} catch (IOException e)
|
{
|
logger.warn(e.getMessage(), e);
|
}
|
}
|
}
|
}
|
|
private void createNewStream() throws IOException, SQLException
|
{
|
if (fos != null)
|
{
|
putEndOfFileElement();
|
fos.close();
|
fos = null;
|
fch = null;
|
}
|
|
File logFile = new File(getDataOutPath(), this.currentSchema + ".dgn");
|
while (logFile.exists())
|
{
|
logFile = new File(getDataOutPath(), this.currentSchema + "-"
|
+ (++logCount) + ".dgn");
|
}
|
|
logger.warn("Create Dgn Logging File:" + logFile.toString());
|
fos = new FileOutputStream(logFile);
|
fch = fos.getChannel();
|
prepareOutputElementStream();
|
schemaChanged = false;
|
elmCount = 0;
|
}
|
|
private void putEndOfFileElement() throws IOException
|
{
|
if (fch == null)
|
return;
|
ByteBuffer bf = ByteBuffer.allocate(4);
|
bf.putInt(-1);
|
fch.write(bf);
|
}
|
|
private void prepareOutputElementStream() throws SQLException, IOException
|
{
|
if (connection == null)
|
{
|
logger.warn("connection is null");
|
return;
|
}
|
|
if (dgnFileHeader != null)
|
{
|
for (byte[] raw : dgnFileHeader)
|
{
|
putElementIntoStream(raw);
|
}
|
return;
|
}
|
|
dgnFileHeader = new ArrayList<byte[]>();
|
String fetchSrcStmtFmt = "SELECT IGDSELM FROM \"%s\".\"%s\" ORDER BY ROWID";
|
PrintfFormat spf = new PrintfFormat(fetchSrcStmtFmt);
|
String fetchSrcStmt = spf.sprintf(new Object[]{currentSchema, TAB_IGDSSEED});
|
Statement stmtSrc = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
|
ResultSet rsSrc = stmtSrc.executeQuery(fetchSrcStmt);
|
int igdsMetaType = rsSrc.getMetaData().getColumnType(1);
|
|
while (rsSrc.next())
|
{
|
byte[] raw;
|
|
if (igdsMetaType == Types.BLOB)
|
{
|
BLOB blob = (BLOB) rsSrc.getBlob(1);
|
|
raw = getBytesFromBLOB(blob);
|
blob.close();
|
} else
|
{
|
raw = rsSrc.getBytes(1);
|
}
|
|
if (raw != null)
|
{
|
dgnFileHeader.add(raw);
|
putElementIntoStream(raw);
|
}
|
}
|
rsSrc.close();
|
stmtSrc.close();
|
}
|
|
private void putElementIntoStream(byte[] raw) throws IOException
|
{
|
if (fch != null)
|
fch.write(ByteBuffer.wrap(raw));
|
}
|
|
protected static byte[] getBytesFromBLOB(BLOB blob) throws SQLException
|
{
|
byte[] raw = null;
|
|
int optimalSize = blob.getChunkSize();
|
byte[] chunk = new byte[optimalSize];
|
InputStream is = blob.getBinaryStream(0);
|
ByteBuffer buffer = null; // ByteBuffer.allocate(optimalSize);
|
int len;
|
|
try
|
{
|
while ((len = (is.read(chunk))) != -1)
|
{
|
if (buffer != null)
|
{
|
buffer.limit(buffer.limit() + len);
|
} else
|
{
|
buffer = ByteBuffer.allocate(len);
|
}
|
|
buffer.put(chunk);
|
}
|
|
is.close();
|
assert buffer != null;
|
buffer.position(0);
|
raw = buffer.array();
|
} catch (IOException e)
|
{
|
logger.warn(e.getMessage(), e);
|
Assert.shouldNeverReachHere();
|
}
|
return raw;
|
}
|
|
public void flashLogging()
|
{
|
if ((useElementCount) && (elmCount < maxElmCount))
|
{
|
return;
|
}
|
|
if (fos != null)
|
{
|
try
|
{
|
putEndOfFileElement();
|
fos.close();
|
} catch (IOException e)
|
{
|
logger.warn(e.getMessage(), e);
|
}
|
fos = null;
|
fch = null;
|
elmCount = 0;
|
}
|
}
|
|
public boolean isSchemaChanged()
|
{
|
return schemaChanged;
|
}
|
|
public boolean isUseElementCount()
|
{
|
return useElementCount;
|
}
|
|
public void setUseElementCount(boolean useElementCount)
|
{
|
this.useElementCount = useElementCount;
|
}
|
|
public int getElmCount()
|
{
|
return elmCount;
|
}
|
|
public int getMaxElmCount()
|
{
|
return maxElmCount;
|
}
|
|
public void setMaxElmCount(int maxElmCount)
|
{
|
this.maxElmCount = maxElmCount;
|
}
|
}
|