use of org.teiid.common.buffer.FileStoreInputStreamFactory in project teiid by teiid.
the class XMLSystemFunctions method saveToBufferManager.
/**
* This method saves the given XML object to the buffer manager's disk process
* Documents less than the maxMemorySize will be held directly in memory
*/
public static SQLXMLImpl saveToBufferManager(BufferManager bufferMgr, XMLTranslator translator, CommandContext context) throws TeiidComponentException, TeiidProcessingException {
boolean success = false;
// $NON-NLS-1$
final FileStore lobBuffer = bufferMgr.createFileStore("xml");
final FileStoreInputStreamFactory fsisf = new FileStoreInputStreamFactory(lobBuffer, Streamable.ENCODING);
try {
Writer writer = fsisf.getWriter();
final ExtendedWriter ew = new ExtendedWriter(writer, fsisf);
translator.translate(ew);
ew.close();
success = true;
return createSQLXML(fsisf, ew, context);
} catch (IOException e) {
throw new TeiidComponentException(QueryPlugin.Event.TEIID30444, e);
} catch (TransformerException e) {
throw new TeiidProcessingException(QueryPlugin.Event.TEIID30445, e);
} finally {
if (!success && lobBuffer != null) {
lobBuffer.remove();
}
}
}
use of org.teiid.common.buffer.FileStoreInputStreamFactory in project teiid by teiid.
the class XMLSystemFunctions method createSQLXML.
private static SQLXMLImpl createSQLXML(final FileStoreInputStreamFactory fsisf, final ExtendedWriter ew, CommandContext context) {
if (ew.includes.isEmpty()) {
if (fsisf.getStorageMode() == StorageMode.MEMORY) {
// detach if just in memory
byte[] bytes = fsisf.getMemoryBytes();
fsisf.free();
return new SQLXMLImpl(bytes);
}
if (context != null) {
context.addCreatedLob(fsisf);
}
return new SQLXMLImpl(fsisf);
}
// TODO: allow the detach to happen even if there are includes
InputStreamFactory isf = new InputStreamFactory() {
@Override
public InputStream getInputStream() throws IOException {
List<InputStream> streams = new ArrayList<InputStream>(ew.includes.size() * 2 + 1);
long last = 0;
for (int i = 0; i < ew.includes.size(); i++) {
Include include = ew.includes.get(i);
streams.add(fsisf.getInputStream(last, include.start - last));
last = include.start;
try {
streams.add(((BaseLob) include.streamable.getReference()).getBinaryStream());
} catch (SQLException e) {
throw new IOException(e);
}
}
streams.add(fsisf.getInputStream(last, -1));
return new SequenceInputStream(Collections.enumeration(streams));
}
@Override
public void free() throws IOException {
fsisf.free();
ew.includes.clear();
}
};
if (context != null) {
context.addCreatedLob(isf);
}
return new SQLXMLImpl(isf);
}
use of org.teiid.common.buffer.FileStoreInputStreamFactory in project teiid by teiid.
the class ConnectorWorkItem method convertToRuntimeType.
static Object convertToRuntimeType(BufferManager bm, Object value, Class<?> desiredType, CommandContext context) throws TransformationException {
if (desiredType != DataTypeManager.DefaultDataClasses.XML || !(value instanceof Source)) {
if (value instanceof DataSource) {
final DataSource ds = (DataSource) value;
try {
// Teiid uses the datasource interface in a degenerate way that
// reuses the stream, so we test for that here
InputStream initial = ds.getInputStream();
InputStream other = null;
try {
other = ds.getInputStream();
} catch (IOException e) {
// likely streaming
}
if (other != null && initial != other) {
initial.close();
other.close();
if (value instanceof InputStreamFactory) {
return asLob((InputStreamFactory) value, desiredType);
}
return asLob(new InputStreamFactory() {
@Override
public InputStream getInputStream() throws IOException {
return ds.getInputStream();
}
}, desiredType);
}
// $NON-NLS-1$
FileStore fs = bm.createFileStore("bytes");
// TODO: guess at the encoding from the content type
FileStoreInputStreamFactory fsisf = new FileStoreInputStreamFactory(fs, Streamable.ENCODING);
SaveOnReadInputStream is = new SaveOnReadInputStream(initial, fsisf);
if (context != null) {
context.addCreatedLob(fsisf);
}
return asLob(is.getInputStreamFactory(), desiredType);
} catch (IOException e) {
throw new TransformationException(QueryPlugin.Event.TEIID30500, e, e.getMessage());
}
}
if (value instanceof InputStreamFactory) {
return asLob((InputStreamFactory) value, desiredType);
}
if (value instanceof GeometryInputSource) {
GeometryInputSource gis = (GeometryInputSource) value;
try {
InputStream is = gis.getEwkb();
if (is != null) {
return GeometryUtils.geometryFromEwkb(is, gis.getSrid());
}
} catch (Exception e) {
throw new TransformationException(e);
}
try {
Reader r = gis.getGml();
if (r != null) {
return GeometryUtils.geometryFromGml(r, gis.getSrid());
}
} catch (Exception e) {
throw new TransformationException(e);
}
}
}
if (value instanceof Source) {
if (!(value instanceof InputStreamFactory)) {
if (value instanceof StreamSource) {
StreamSource ss = (StreamSource) value;
InputStream is = ss.getInputStream();
Reader r = ss.getReader();
if (is == null && r != null) {
is = new ReaderInputStream(r, Streamable.CHARSET);
}
// $NON-NLS-1$
final FileStore fs = bm.createFileStore("xml");
final FileStoreInputStreamFactory fsisf = new FileStoreInputStreamFactory(fs, Streamable.ENCODING);
value = new SaveOnReadInputStream(is, fsisf).getInputStreamFactory();
if (context != null) {
context.addCreatedLob(fsisf);
}
} else if (value instanceof StAXSource) {
// TODO: do this lazily. if the first access to get the STaXSource, then
// it's more efficient to let the processing happen against STaX
StAXSource ss = (StAXSource) value;
try {
// $NON-NLS-1$
final FileStore fs = bm.createFileStore("xml");
final FileStoreInputStreamFactory fsisf = new FileStoreInputStreamFactory(fs, Streamable.ENCODING);
value = new SaveOnReadInputStream(new XMLInputStream(ss, XMLSystemFunctions.getOutputFactory(true)), fsisf).getInputStreamFactory();
if (context != null) {
context.addCreatedLob(fsisf);
}
} catch (XMLStreamException e) {
throw new TransformationException(e);
}
} else {
// maybe dom or some other source we want to get out of memory
StandardXMLTranslator sxt = new StandardXMLTranslator((Source) value);
SQLXMLImpl sqlxml;
try {
sqlxml = XMLSystemFunctions.saveToBufferManager(bm, sxt, context);
} catch (TeiidComponentException e) {
throw new TransformationException(e);
} catch (TeiidProcessingException e) {
throw new TransformationException(e);
}
return new XMLType(sqlxml);
}
}
return new XMLType(new SQLXMLImpl((InputStreamFactory) value));
}
return DataTypeManager.convertToRuntimeType(value, desiredType != DataTypeManager.DefaultDataClasses.OBJECT);
}
use of org.teiid.common.buffer.FileStoreInputStreamFactory in project teiid by teiid.
the class ObjectDecoder method decode.
@Override
protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
if (result == null) {
ByteBuf frame = null;
try {
frame = (ByteBuf) super.decode(ctx, buffer);
} catch (TooLongFrameException e) {
throw new IOException(RuntimePlugin.Util.gs(RuntimePlugin.Event.TEIID40166), e);
}
if (frame == null) {
return null;
}
CompactObjectInputStream cois = new CompactObjectInputStream(new ByteBufInputStream(frame), classLoader);
result = cois.readObject();
streams = ExternalizeUtil.readList(cois, StreamFactoryReference.class);
streamIndex = 0;
}
while (streamIndex < streams.size()) {
// read the new chunk size
if (streamDataToRead == -1) {
if (buffer.readableBytes() < 2) {
return null;
}
streamDataToRead = buffer.readUnsignedShort();
}
if (stream == null) {
// $NON-NLS-1$
store = storageManager.createFileStore("temp-stream");
StreamFactoryReference sfr = streams.get(streamIndex);
sfr.setStreamFactory(new FileStoreInputStreamFactory(store, Streamable.ENCODING));
this.stream = new BufferedOutputStream(store.createOutputStream());
}
// end of stream
if (streamDataToRead == 0) {
stream.close();
stream = null;
streamIndex++;
streamDataToRead = -1;
continue;
}
if (store.getLength() + streamDataToRead > maxLobSize) {
if (error == null) {
error = new StreamCorruptedException(// $NON-NLS-1$ //$NON-NLS-2$
"lob too big: " + (store.getLength() + streamDataToRead) + " (max: " + maxLobSize + ')');
}
}
int toRead = Math.min(buffer.readableBytes(), streamDataToRead);
if (toRead == 0) {
return null;
}
if (error == null) {
buffer.readBytes(this.stream, toRead);
} else {
buffer.skipBytes(toRead);
}
streamDataToRead -= toRead;
if (streamDataToRead == 0) {
// get the next chunk
streamDataToRead = -1;
}
}
Object toReturn = result;
result = null;
streams = null;
stream = null;
store = null;
if (error != null) {
StreamCorruptedException sce = error;
error = null;
throw sce;
}
return toReturn;
}
use of org.teiid.common.buffer.FileStoreInputStreamFactory in project teiid by teiid.
the class PreparedStatementRequest method createStreamCopy.
/**
* embedded lobs can be sent with just a reference to a stream,
* create a copy instead
* @param context
* @param i
* @param param
* @param value
* @throws QueryResolverException
*/
private static void createStreamCopy(CommandContext context, int i, Reference param, Object value) throws QueryResolverException {
try {
InputStreamFactory isf = ((BaseLob) value).getStreamFactory();
InputStream initial = isf.getInputStream();
InputStream other = isf.getInputStream();
if (initial == other) {
// this violates the expectation that the inputstream is a new instance,
// $NON-NLS-1$
FileStore fs = context.getBufferManager().createFileStore("bytes");
FileStoreInputStreamFactory fsisf = new FileStoreInputStreamFactory(fs, Streamable.ENCODING);
SaveOnReadInputStream is = new SaveOnReadInputStream(initial, fsisf);
context.addCreatedLob(fsisf);
((BaseLob) value).setStreamFactory(is.getInputStreamFactory());
} else {
initial.close();
other.close();
}
} catch (SQLException e) {
// $NON-NLS-1$
String msg = QueryPlugin.Util.getString("QueryUtil.Error_executing_conversion_function_to_convert_value", i + 1, value, value.getClass(), DataTypeManager.getDataTypeName(param.getType()));
throw new QueryResolverException(QueryPlugin.Event.TEIID30557, e, msg);
} catch (IOException e) {
// $NON-NLS-1$
String msg = QueryPlugin.Util.getString("QueryUtil.Error_executing_conversion_function_to_convert_value", i + 1, value, value.getClass(), DataTypeManager.getDataTypeName(param.getType()));
throw new QueryResolverException(QueryPlugin.Event.TEIID30557, e, msg);
}
}
Aggregations