package com.ximple.io.dgn7;
|
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.nio.ByteBuffer;
|
import java.nio.ByteOrder;
|
import java.sql.Connection;
|
import java.sql.ResultSet;
|
import java.sql.SQLException;
|
import java.sql.Statement;
|
import java.util.Iterator;
|
|
import org.apache.log4j.Logger;
|
|
import oracle.jdbc.OracleConnection;
|
import oracle.sql.BLOB;
|
|
/**
|
* Dgn7OracleReader
|
* User: Ulysses
|
* Date: 2007/10/24
|
* Time: 下午 01:01:08
|
*/
|
public class Dgn7OracleReader implements Iterator<Element>
|
{
|
private final static Logger logger = Logger.getLogger(Dgn7OracleReader.class);
|
|
private String _sql;
|
private String _fieldName;
|
private Connection _connection;
|
private ResultSet _resultSet;
|
private static final int FETCHSIZE = 20;
|
private Element _element;
|
|
public Dgn7OracleReader(String sql, String fieldName, OracleConnection connection)
|
{
|
this._sql = sql;
|
this._fieldName = fieldName;
|
this._connection = connection;
|
}
|
|
public String getSql()
|
{
|
return _sql;
|
}
|
|
public void setSql(String sql)
|
{
|
this._sql = sql;
|
}
|
|
public String getFieldName()
|
{
|
return _fieldName;
|
}
|
|
public void setFieldName(String fieldName)
|
{
|
this._fieldName = fieldName;
|
}
|
|
public boolean hasNext()
|
{
|
if (_resultSet == null)
|
{
|
try
|
{
|
initializeReader();
|
} catch (SQLException e)
|
{
|
throw new RuntimeException("initialize oralce error.", e);
|
} catch (Dgn7Exception e)
|
{
|
throw new RuntimeException("initialize oralce error.", e);
|
}
|
}
|
return _element != null;
|
}
|
|
public Element next()
|
{
|
Element result = _element;
|
|
try
|
{
|
fetchElement();
|
} catch (SQLException e)
|
{
|
throw new RuntimeException("Error:" + e.getMessage(), e);
|
} catch (Dgn7Exception e)
|
{
|
throw new RuntimeException("Error:" + e.getMessage(), e);
|
}
|
|
return result;
|
}
|
|
public void remove()
|
{
|
throw new RuntimeException("Not Support this method.");
|
}
|
|
private boolean initializeReader() throws SQLException, Dgn7Exception
|
{
|
if (_resultSet != null) return true;
|
Statement stmtSrc = _connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
|
|
stmtSrc.setFetchSize(FETCHSIZE);
|
_resultSet = stmtSrc.executeQuery(_sql);
|
|
fetchElement();
|
|
return true;
|
}
|
|
private boolean fetchElement() throws SQLException, Dgn7Exception
|
{
|
if (_resultSet.next())
|
{
|
byte[] raw = null;
|
Object value = _resultSet.getObject(this._fieldName);
|
|
if (value instanceof BLOB)
|
{
|
BLOB blob = (BLOB) value;
|
|
try
|
{
|
raw = getBytesFromBLOB(blob);
|
} catch (IOException e)
|
{
|
throw new Dgn7Exception("IOError", e);
|
}
|
blob.close();
|
} else if (value instanceof byte[])
|
{
|
raw = (byte[]) value;
|
}
|
if (raw == null)
|
{
|
_element = null;
|
return false;
|
}
|
|
ByteBuffer buffer = ByteBuffer.wrap(raw);
|
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
short signature = buffer.getShort();
|
|
// byte type = (byte) (buffer.get() & 0x7f);
|
byte type = (byte) ((signature >>> 8) & 0x007f);
|
|
// silly Bentley say contentLength is in 2-byte words
|
// and ByteByffer uses bytes.
|
// track the record location
|
int elementLength = (buffer.getShort() * 2) + 4;
|
ElementType recordType = ElementType.forID(type);
|
IElementHandler handler = recordType.getElementHandler();
|
_element = (Element) handler.read(buffer, signature, elementLength);
|
if (recordType.isComplexElement() && (elementLength < raw.length))
|
{
|
int offset = elementLength;
|
while (offset < (raw.length - 4))
|
{
|
buffer.position(offset);
|
signature = buffer.getShort();
|
type = (byte) ((signature >>> 8) & 0x007f);
|
elementLength = (buffer.getShort() * 2) + 4;
|
if (raw.length < (offset + elementLength))
|
{
|
System.out.println("Length not match:" + offset +":"+ buffer.position() +":"+buffer.limit());
|
break;
|
}
|
recordType = ElementType.forID(type);
|
handler = recordType.getElementHandler();
|
if (handler != null)
|
{
|
Element subElement = (Element) handler.read(buffer, signature, elementLength);
|
((ComplexElement) _element).add(subElement);
|
offset += elementLength;
|
} else
|
{
|
byte[] remain = new byte[buffer.remaining()];
|
System.arraycopy(raw, offset, remain, 0, buffer.remaining());
|
for (int i = 0; i < remain.length; i++)
|
{
|
if (remain[i] != 0)
|
{
|
logger.info("fetch element has some error. index=" + (offset + i) + ":value=" + remain[i]);
|
System.out.println("fetch element has some error. index=" + (offset + i) + ":value=" + remain[i]);
|
}
|
}
|
break;
|
}
|
}
|
}
|
|
} else
|
{
|
_element = null;
|
return false;
|
}
|
return true;
|
}
|
|
protected static byte[] getBytesFromBLOB(BLOB blob) throws SQLException, IOException
|
{
|
byte[] raw;
|
|
// BLOB blob = (BLOB) rs.getBlob(1);
|
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)
|
{
|
e.printStackTrace();
|
throw e;
|
}
|
|
return raw;
|
}
|
}
|