[teiid-commits] teiid SVN: r2233 - in trunk: client/src/main/java/org/teiid/jdbc and 32 other directories.
teiid-commits at lists.jboss.org
teiid-commits at lists.jboss.org
Tue Jun 15 12:49:32 EDT 2010
Author: shawkins
Date: 2010-06-15 12:49:28 -0400 (Tue, 15 Jun 2010)
New Revision: 2233
Added:
trunk/engine/src/main/java/org/teiid/query/sql/symbol/XMLParse.java
Removed:
trunk/common-core/src/main/java/org/teiid/core/types/basic/ClobToSQLXMLTransform.java
trunk/common-core/src/main/java/org/teiid/core/types/basic/SQLXMLToClobTransform.java
trunk/common-core/src/test/java/org/teiid/api/exception/
trunk/common-core/src/test/java/org/teiid/common/util/
trunk/engine/src/main/java/org/teiid/query/processor/xml/SAXDocumentInProgress.java
Modified:
trunk/api/src/main/java/org/teiid/language/SQLConstants.java
trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java
trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java
trunk/client/src/main/java/org/teiid/netty/handler/codec/serialization/CompactObjectOutputStream.java
trunk/common-core/src/main/java/org/teiid/core/types/DataTypeManager.java
trunk/common-core/src/main/java/org/teiid/core/types/InputStreamFactory.java
trunk/common-core/src/main/java/org/teiid/core/types/SQLXMLImpl.java
trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java
trunk/common-core/src/main/java/org/teiid/core/types/basic/StringToSQLXMLTransform.java
trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java
trunk/common-core/src/main/java/org/teiid/core/util/ReaderInputStream.java
trunk/common-core/src/main/resources/org/teiid/core/i18n.properties
trunk/common-core/src/test/java/org/teiid/core/types/TestDataTypeManager.java
trunk/documentation/reference/src/main/docbook/en-US/content/datatypes.xml
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
trunk/engine/src/main/java/org/teiid/common/buffer/FileStore.java
trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/ByteLobChunkStream.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/LobWorkItem.java
trunk/engine/src/main/java/org/teiid/metadata/TransformationMetadata.java
trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java
trunk/engine/src/main/java/org/teiid/query/function/source/XMLSystemFunctions.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
trunk/engine/src/main/java/org/teiid/query/processor/xml/DocumentInProgress.java
trunk/engine/src/main/java/org/teiid/query/processor/xml/InitializeDocumentInstruction.java
trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLPlan.java
trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLUtil.java
trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java
trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
trunk/engine/src/main/java/org/teiid/query/xquery/saxon/SaxonXQueryExpression.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatement.java
trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestRequest.java
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
trunk/engine/src/test/java/org/teiid/query/processor/TestTextTable.java
trunk/engine/src/test/java/org/teiid/query/processor/xml/TestAddNodeInstruction.java
trunk/engine/src/test/java/org/teiid/query/processor/xml/TestSAXDocumentInProgress.java
trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
Log:
TEIID-1024 added xmlparse/xmlserialize to augment basic convert support. also ensuring that encoding will be null if it is not known.
Modified: trunk/api/src/main/java/org/teiid/language/SQLConstants.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -82,8 +82,10 @@
public static final String RETURNING = "RETURNING"; //$NON-NLS-1$
public static final String SEQUENCE = "SEQUENCE"; //$NON-NLS-1$
public static final String EMPTY = "EMPTY"; //$NON-NLS-1$
-
+ //querystring function
public static final String QUERYSTRING = "QUERYSTRING"; //$NON-NLS-1$
+ //xmlparse
+ public static final String WELLFORMED = "WELLFORMED"; //$NON-NLS-1$
}
public interface Reserved {
Modified: trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/client/src/main/java/org/teiid/jdbc/PreparedStatementImpl.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -61,6 +61,7 @@
import org.teiid.core.types.ClobImpl;
import org.teiid.core.types.InputStreamFactory;
import org.teiid.core.types.JDBCSQLTypeInfo;
+import org.teiid.core.types.Streamable;
import org.teiid.core.util.ArgCheck;
import org.teiid.core.util.ReaderInputStream;
import org.teiid.core.util.SqlUtil;
@@ -725,11 +726,11 @@
}
public void setClob(int parameterIndex, final Reader reader) throws SQLException {
- this.setObject(parameterIndex, new ClobImpl(new InputStreamFactory() {
+ this.setObject(parameterIndex, new ClobImpl(new InputStreamFactory(Streamable.ENCODING) {
@Override
public InputStream getInputStream() throws IOException {
- return new ReaderInputStream(reader, Charset.defaultCharset());
+ return new ReaderInputStream(reader, Charset.forName(Streamable.ENCODING));
}
}, -1));
}
Modified: trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/client/src/main/java/org/teiid/jdbc/ResultSetImpl.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -295,15 +295,15 @@
}
}
if(currentValue instanceof ClobType){
- currentValue = new ClobImpl(createInputStreamFactory((ClobType)currentValue), ((ClobType)currentValue).getLength());
+ currentValue = new ClobImpl(createInputStreamFactory((ClobType)currentValue, null), ((ClobType)currentValue).getLength());
}
else if (currentValue instanceof BlobType) {
- InputStreamFactory isf = createInputStreamFactory((BlobType)currentValue);
+ InputStreamFactory isf = createInputStreamFactory((BlobType)currentValue, null);
isf.setLength(((BlobType)currentValue).getLength());
currentValue = new BlobImpl(isf);
}
else if (currentValue instanceof XMLType) {
- currentValue = new SQLXMLImpl(createInputStreamFactory((XMLType)currentValue));
+ currentValue = new SQLXMLImpl(createInputStreamFactory((XMLType)currentValue, ((XMLType)currentValue).getEncoding()));
}
}
else if (currentValue instanceof java.util.Date) {
@@ -315,10 +315,13 @@
}
return currentValue;
}
-
- private InputStreamFactory createInputStreamFactory(Streamable<?> type) {
+
+ private InputStreamFactory createInputStreamFactory(Streamable<?> type, String encoding) {
+ if (encoding == null) {
+ encoding = Streamable.ENCODING;
+ }
final StreamingLobChunckProducer.Factory factory = new StreamingLobChunckProducer.Factory(this.statement.getDQP(), this.requestID, type);
- InputStreamFactory isf = new InputStreamFactory(Streamable.ENCODING) {
+ InputStreamFactory isf = new InputStreamFactory(encoding) {
@Override
public InputStream getInputStream() throws IOException {
return new LobChunkInputStream(factory.getLobChunkProducer());
Modified: trunk/client/src/main/java/org/teiid/netty/handler/codec/serialization/CompactObjectOutputStream.java
===================================================================
--- trunk/client/src/main/java/org/teiid/netty/handler/codec/serialization/CompactObjectOutputStream.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/client/src/main/java/org/teiid/netty/handler/codec/serialization/CompactObjectOutputStream.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -201,6 +201,7 @@
references.add(sfr);
return sfr;
} else if (obj instanceof Clob) {
+ //TODO: see if this is a ClobImpl and grab the underlying stream
streams.add(new ReaderInputStream(((Clob)obj).getCharacterStream(), Charset.forName(Streamable.ENCODING)));
StreamFactoryReference sfr = new ClobImpl();
references.add(sfr);
Modified: trunk/common-core/src/main/java/org/teiid/core/types/DataTypeManager.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/DataTypeManager.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/common-core/src/main/java/org/teiid/core/types/DataTypeManager.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -48,7 +48,6 @@
import org.teiid.core.types.basic.AnyToObjectTransform;
import org.teiid.core.types.basic.AnyToStringTransform;
import org.teiid.core.types.basic.BooleanToNumberTransform;
-import org.teiid.core.types.basic.ClobToSQLXMLTransform;
import org.teiid.core.types.basic.FixedNumberToBigDecimalTransform;
import org.teiid.core.types.basic.FixedNumberToBigIntegerTransform;
import org.teiid.core.types.basic.FloatingNumberToBigDecimalTransform;
@@ -62,7 +61,6 @@
import org.teiid.core.types.basic.NumberToLongTransform;
import org.teiid.core.types.basic.NumberToShortTransform;
import org.teiid.core.types.basic.ObjectToAnyTransform;
-import org.teiid.core.types.basic.SQLXMLToClobTransform;
import org.teiid.core.util.ArgCheck;
import org.teiid.core.util.HashCodeUtil;
import org.teiid.core.util.PropertiesUtils;
@@ -135,6 +133,7 @@
private static Map<Class<?>, ValueCache<?>> valueMaps = new HashMap<Class<?>, ValueCache<?>>(128);
public static final int MAX_STRING_LENGTH = 4000;
+ public static final int MAX_LOB_MEMORY_BYTES = 1 << 13;
public static final class DataTypeAliases {
public static final String VARCHAR = "varchar"; //$NON-NLS-1$
@@ -688,11 +687,9 @@
DataTypeManager.addTransform(new org.teiid.core.types.basic.StringToSQLXMLTransform());
DataTypeManager.addTransform(new org.teiid.core.types.basic.ClobToStringTransform());
- DataTypeManager.addTransform(new ClobToSQLXMLTransform());
-
- DataTypeManager.addTransform(new org.teiid.core.types.basic.SQLXMLToStringTransform());
- DataTypeManager.addTransform(new SQLXMLToClobTransform());
+ DataTypeManager.addTransform(new org.teiid.core.types.basic.SQLXMLToStringTransform());
+
for (Class<?> type : getAllDataTypeClasses()) {
if (type != DefaultDataClasses.OBJECT) {
DataTypeManager.addTransform(new AnyToObjectTransform(type));
Modified: trunk/common-core/src/main/java/org/teiid/core/types/InputStreamFactory.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/InputStreamFactory.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/common-core/src/main/java/org/teiid/core/types/InputStreamFactory.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -30,9 +30,15 @@
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
+import java.sql.SQLXML;
import javax.xml.transform.Source;
+import org.teiid.core.util.ReaderInputStream;
+
public abstract class InputStreamFactory implements Source {
public interface StreamFactoryReference {
@@ -46,7 +52,6 @@
private long length = -1;
public InputStreamFactory() {
- this(Charset.defaultCharset().name());
}
public InputStreamFactory(String encoding) {
@@ -63,6 +68,10 @@
return encoding;
}
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
@Override
public String getSystemId() {
return this.systemId;
@@ -86,7 +95,11 @@
}
public Reader getCharacterStream() throws IOException {
- return new InputStreamReader(this.getInputStream(), this.getEncoding());
+ String enc = this.getEncoding();
+ if (enc == null) {
+ enc = Charset.defaultCharset().displayName();
+ }
+ return new InputStreamReader(this.getInputStream(), enc);
}
public static class FileInputStreamFactory extends InputStreamFactory {
@@ -94,7 +107,7 @@
private File f;
public FileInputStreamFactory(File f) {
- this(f, Charset.defaultCharset().displayName());
+ this(f, null);
}
public FileInputStreamFactory(File f, String encoding) {
@@ -115,4 +128,89 @@
}
+ public static class ClobInputStreamFactory extends InputStreamFactory {
+
+ private Clob clob;
+
+ public ClobInputStreamFactory(Clob clob) {
+ super(Streamable.ENCODING);
+ this.clob = clob;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ try {
+ return new ReaderInputStream(clob.getCharacterStream(), Charset.forName(Streamable.ENCODING));
+ } catch (SQLException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public Reader getCharacterStream() throws IOException {
+ try {
+ return clob.getCharacterStream();
+ } catch (SQLException e) {
+ throw new IOException(e);
+ }
+ }
+
+ }
+
+ public static class BlobInputStreamFactory extends InputStreamFactory {
+
+ private Blob blob;
+
+ public BlobInputStreamFactory(Blob blob) {
+ this.blob = blob;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ try {
+ return blob.getBinaryStream();
+ } catch (SQLException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public long getLength() {
+ try {
+ return blob.length();
+ } catch (SQLException e) {
+ return -1;
+ }
+ }
+
+ }
+
+ public static class SQLXMLInputStreamFactory extends InputStreamFactory {
+
+ private SQLXML sqlxml;
+
+ public SQLXMLInputStreamFactory(SQLXML sqlxml) {
+ this.sqlxml = sqlxml;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ try {
+ return sqlxml.getBinaryStream();
+ } catch (SQLException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public Reader getCharacterStream() throws IOException {
+ try {
+ return sqlxml.getCharacterStream();
+ } catch (SQLException e) {
+ throw new IOException(e);
+ }
+ }
+
+ }
+
}
Modified: trunk/common-core/src/main/java/org/teiid/core/types/SQLXMLImpl.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/SQLXMLImpl.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/common-core/src/main/java/org/teiid/core/types/SQLXMLImpl.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -26,24 +26,39 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.sql.SQLException;
import java.sql.SQLXML;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamSource;
import org.teiid.core.util.ObjectConverterUtil;
import org.teiid.core.util.SqlUtil;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
-
-
/**
* Default SQLXML impl
+ *
+ * NOTE that this representation of XML does not become unreadable after
+ * read operations.
*/
public class SQLXMLImpl extends BaseLob implements SQLXML {
+
+ private boolean inMemory;
public SQLXMLImpl() {
@@ -60,6 +75,7 @@
return new ByteArrayInputStream(bytes);
}
});
+ inMemory = true;
}
public SQLXMLImpl(final String str) {
@@ -70,17 +86,57 @@
super(factory);
}
+ @Override
+ public Reader getCharacterStream() throws SQLException {
+ setEncoding();
+ return super.getCharacterStream();
+ }
+
+ private void setEncoding() throws SQLException {
+ String encoding = XMLType.getEncoding(this);
+ if (encoding != null) {
+ this.getStreamFactory().setEncoding(encoding);
+ }
+ }
+
+ public boolean isInMemory() {
+ return inMemory;
+ }
+
@SuppressWarnings("unchecked")
public <T extends Source> T getSource(Class<T> sourceClass) throws SQLException {
if (sourceClass == null || sourceClass == StreamSource.class) {
return (T)new StreamSource(getBinaryStream(), this.getStreamFactory().getSystemId());
+ } else if (sourceClass == StAXSource.class) {
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ try {
+ return (T) new StAXSource(factory.createXMLStreamReader(getBinaryStream()));
+ } catch (XMLStreamException e) {
+ throw new SQLException(e);
+ }
+ } else if (sourceClass == SAXSource.class) {
+ return (T) new SAXSource(new InputSource(getBinaryStream()));
+ } else if (sourceClass == DOMSource.class) {
+ try {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ DocumentBuilder docBuilder = dbf.newDocumentBuilder();
+ Node doc = docBuilder.parse(new InputSource(getBinaryStream()));
+ return (T) new DOMSource(doc);
+ } catch (ParserConfigurationException e) {
+ throw new SQLException(e);
+ } catch (SAXException e) {
+ throw new SQLException(e);
+ } catch (IOException e) {
+ throw new SQLException(e);
+ }
}
throw new SQLException("Unsupported source type " + sourceClass); //$NON-NLS-1$
}
public String getString() throws SQLException {
try {
- return new String(ObjectConverterUtil.convertToByteArray(getBinaryStream()), this.getStreamFactory().getEncoding());
+ return ObjectConverterUtil.convertToString(getCharacterStream());
} catch (IOException e) {
SQLException ex = new SQLException(e.getMessage());
ex.initCause(e);
@@ -100,14 +156,6 @@
throw SqlUtil.createFeatureNotSupportedException();
}
- public String toString() {
- try {
- return getString();
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
-
public <T extends Result> T setResult(Class<T> resultClass)
throws SQLException {
throw SqlUtil.createFeatureNotSupportedException();
Modified: trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -22,26 +22,27 @@
package org.teiid.core.types;
+import java.io.IOException;
import java.io.InputStream;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.sql.SQLException;
-//## JDBC4.0-begin ##
import java.sql.SQLXML;
-//## JDBC4.0-end ##
-/*## JDBC3.0-JDK1.5-begin ##
-import com.metamatrix.core.jdbc.SQLXML;
-## JDBC3.0-JDK1.5-end ##*/
-
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
/**
- * This class represents the SQLXML object along with the Streamable interface. This is
- * class used everywhere in the MetaMatrix framework, but clients are restricted to use
- * only SQLXML interface on top of this.
+ * This class represents the SQLXML object along with the Streamable interface.
+ *
+ * NOTE that this representation of XML does not become unreadable after
+ * read operations.
*/
public final class XMLType extends Streamable<SQLXML> implements SQLXML {
@@ -52,6 +53,7 @@
private static final long serialVersionUID = -7922647237095135723L;
private transient Type type = Type.UNKNOWN;
+ private String encoding;
public XMLType(){
@@ -106,4 +108,70 @@
this.type = type;
}
+ public Boolean isInMemory() {
+ if (this.reference instanceof SQLXMLImpl) {
+ return (((SQLXMLImpl) this.reference).isInMemory());
+ }
+ return null;
+ }
+
+ public String getEncoding() {
+ return encoding;
+ }
+
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ super.readExternal(in);
+ this.encoding = (String)in.readObject();
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal(out);
+ if (this.encoding == null) {
+ this.encoding = getEncoding(this);
+ }
+ out.writeObject(this.encoding);
+ }
+
+ /**
+ * Returns the encoding or null if it cannot be determined
+ * @param xml
+ * @return
+ */
+ public static String getEncoding(SQLXML xml) {
+ InputStream is = null;
+ try {
+ if (xml instanceof XMLType) {
+ XMLType type = (XMLType)xml;
+ xml = type.reference;
+ }
+ if (xml instanceof SQLXMLImpl) {
+ String encoding = ((SQLXMLImpl)xml).getStreamFactory().getEncoding();
+ if (encoding != null) {
+ return encoding;
+ }
+ }
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ is = xml.getBinaryStream();
+ XMLStreamReader reader = factory.createXMLStreamReader(is);
+ return reader.getEncoding();
+ } catch (SQLException e) {
+ return null;
+ } catch (XMLStreamException e) {
+ return null;
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
}
Deleted: trunk/common-core/src/main/java/org/teiid/core/types/basic/ClobToSQLXMLTransform.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/basic/ClobToSQLXMLTransform.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/common-core/src/main/java/org/teiid/core/types/basic/ClobToSQLXMLTransform.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -1,108 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package org.teiid.core.types.basic;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.nio.charset.Charset;
-import java.sql.SQLException;
-
-import org.teiid.core.CorePlugin;
-import org.teiid.core.types.ClobImpl;
-import org.teiid.core.types.ClobType;
-import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.types.InputStreamFactory;
-import org.teiid.core.types.SQLXMLImpl;
-import org.teiid.core.types.Streamable;
-import org.teiid.core.types.Transform;
-import org.teiid.core.types.TransformationException;
-import org.teiid.core.types.XMLType;
-import org.teiid.core.types.XMLType.Type;
-import org.teiid.core.util.ReaderInputStream;
-
-
-public class ClobToSQLXMLTransform extends Transform {
-
- @Override
- public Class<?> getSourceType() {
- return DataTypeManager.DefaultDataClasses.CLOB;
- }
-
- @Override
- public Class<?> getTargetType() {
- return DataTypeManager.DefaultDataClasses.XML;
- }
-
- /**
- * This method transforms a value of the source type into a value
- * of the target type.
- * @param value Incoming value of source type
- * @return Outgoing value of target type
- * @throws TransformationException if value is an incorrect input type or
- * the transformation fails
- */
- public Object transformDirect(Object value) throws TransformationException {
- final ClobType source = (ClobType)value;
-
- Reader reader = null;
- try {
- reader = source.getCharacterStream();
- XMLType result = null;
- Type type = StringToSQLXMLTransform.isXml(reader);
- if (source.getReference() instanceof ClobImpl) {
- ClobImpl clob = (ClobImpl)source.getReference();
- result = new XMLType(new SQLXMLImpl(clob.getStreamFactory()));
- } else {
- result = new XMLType(new SQLXMLImpl(new InputStreamFactory(Streamable.ENCODING) {
- @Override
- public InputStream getInputStream() throws IOException {
- try {
- return new ReaderInputStream(source.getCharacterStream(), Charset.forName(Streamable.ENCODING));
- } catch (SQLException e) {
- throw new IOException(e);
- }
- }
- }));
- }
- result.setType(type);
- return result;
- } catch (SQLException e) {
- throw new TransformationException(e, CorePlugin.Util.getString("failed_convert", new Object[] {getSourceType().getName(), getTargetType().getName()})); //$NON-NLS-1$
- } finally {
- if (reader != null) {
- try {
- reader.close();
- } catch (IOException e) {
- }
- }
- }
- }
-
- /**
- * @see org.teiid.core.types.Transform#isExplicit()
- */
- public boolean isExplicit() {
- return true;
- }
-}
Deleted: trunk/common-core/src/main/java/org/teiid/core/types/basic/SQLXMLToClobTransform.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/basic/SQLXMLToClobTransform.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/common-core/src/main/java/org/teiid/core/types/basic/SQLXMLToClobTransform.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -1,92 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package org.teiid.core.types.basic;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.sql.SQLException;
-
-import org.teiid.core.CorePlugin;
-import org.teiid.core.types.ClobImpl;
-import org.teiid.core.types.ClobType;
-import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.types.InputStreamFactory;
-import org.teiid.core.types.SQLXMLImpl;
-import org.teiid.core.types.Streamable;
-import org.teiid.core.types.Transform;
-import org.teiid.core.types.TransformationException;
-import org.teiid.core.types.XMLType;
-import org.teiid.core.util.ReaderInputStream;
-
-
-public class SQLXMLToClobTransform extends Transform {
-
- @Override
- public Class<?> getSourceType() {
- return DataTypeManager.DefaultDataClasses.XML;
- }
-
- @Override
- public Class<?> getTargetType() {
- return DataTypeManager.DefaultDataClasses.CLOB;
- }
-
- /**
- * This method transforms a value of the source type into a value
- * of the target type.
- * @param value Incoming value of source type
- * @return Outgoing value of target type
- * @throws TransformationException if value is an incorrect input type or
- * the transformation fails
- */
- public Object transformDirect(Object value) throws TransformationException {
- final XMLType source = (XMLType)value;
-
- try {
- if (source.getReference() instanceof SQLXMLImpl) {
- SQLXMLImpl xml = (SQLXMLImpl)source.getReference();
- return new ClobType(new ClobImpl(xml.getStreamFactory(), -1));
- }
- return new ClobType(new ClobImpl(new InputStreamFactory(Streamable.ENCODING) {
- @Override
- public InputStream getInputStream() throws IOException {
- try {
- return new ReaderInputStream(source.getCharacterStream(), Charset.forName(Streamable.ENCODING));
- } catch (SQLException e) {
- throw new IOException(e);
- }
- }
- }, -1));
- } catch (SQLException e) {
- throw new TransformationException(e, CorePlugin.Util.getString("failed_convert", new Object[] {getSourceType().getName(), getTargetType().getName()})); //$NON-NLS-1$
- }
- }
-
- /**
- * @see org.teiid.core.types.Transform#isExplicit()
- */
- public boolean isExplicit() {
- return true;
- }
-}
Modified: trunk/common-core/src/main/java/org/teiid/core/types/basic/StringToSQLXMLTransform.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/basic/StringToSQLXMLTransform.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/common-core/src/main/java/org/teiid/core/types/basic/StringToSQLXMLTransform.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -26,8 +26,8 @@
import java.io.Reader;
import java.io.StringReader;
-import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;
import org.teiid.core.CorePlugin;
@@ -62,12 +62,13 @@
Type type = Type.ELEMENT;
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
try{
- XMLEventReader xmlReader = inputFactory.createXMLEventReader(reader);
+ XMLStreamReader xmlReader = inputFactory.createXMLStreamReader(reader);
+ int event = xmlReader.getEventType();
+ if (event == XMLEvent.START_DOCUMENT && xmlReader.getLocation().getColumnNumber() != 1) {
+ type = Type.DOCUMENT;
+ }
while (xmlReader.hasNext()) {
- XMLEvent event = xmlReader.nextEvent();
- if (event.isStartDocument() && event.getLocation().getColumnNumber() != 1) {
- type = Type.DOCUMENT;
- }
+ xmlReader.next();
}
} catch (Exception e){
throw new TransformationException(e, CorePlugin.Util.getString("invalid_string")); //$NON-NLS-1$
Modified: trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -109,8 +109,11 @@
writen += l_nbytes;
}
} finally {
- is.close();
- out.close();
+ try {
+ is.close();
+ } finally {
+ out.close();
+ }
}
}
@@ -128,8 +131,11 @@
writen += l_nbytes;
}
} finally {
- is.close();
- out.close();
+ try {
+ is.close();
+ } finally {
+ out.close();
+ }
}
}
Modified: trunk/common-core/src/main/java/org/teiid/core/util/ReaderInputStream.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/util/ReaderInputStream.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/common-core/src/main/java/org/teiid/core/util/ReaderInputStream.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -32,12 +32,11 @@
import java.nio.CharBuffer;
import java.nio.charset.Charset;
-import org.teiid.core.types.Streamable;
+import org.teiid.core.types.DataTypeManager;
-
public class ReaderInputStream extends InputStream {
- private static final int DEFAULT_BUFFER_SIZE = Streamable.STREAMING_BATCH_SIZE_IN_BYTES;
+ private static final int DEFAULT_BUFFER_SIZE = DataTypeManager.MAX_LOB_MEMORY_BYTES;
private final Reader reader;
private final Charset charSet;
Modified: trunk/common-core/src/main/resources/org/teiid/core/i18n.properties
===================================================================
--- trunk/common-core/src/main/resources/org/teiid/core/i18n.properties 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/common-core/src/main/resources/org/teiid/core/i18n.properties 2010-06-15 16:49:28 UTC (rev 2233)
@@ -314,7 +314,7 @@
lob.invaliddata=Invalid type of data has been retrieved from server.
remote_lob_access=Lob object accessed is from a remote connector; Can not stream data from remote objects;
failed_convert=Failed to convert {0} into {1}
-invalid_string=Not valid String to transform to XML
+invalid_string=Value is not valid XML
ClobImpl.Failed_copy_clob=Failed creating a new clob from the given clob: {0}.
ClobImpl.Invalid_substring_position=The substring position "{0}" is not valid.
Modified: trunk/common-core/src/test/java/org/teiid/core/types/TestDataTypeManager.java
===================================================================
--- trunk/common-core/src/test/java/org/teiid/core/types/TestDataTypeManager.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/common-core/src/test/java/org/teiid/core/types/TestDataTypeManager.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -26,22 +26,16 @@
import java.sql.Types;
import java.util.Arrays;
-import java.util.Iterator;
import java.util.Set;
import javax.sql.rowset.serial.SerialBlob;
import org.junit.Test;
-import org.teiid.core.types.BlobType;
-import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.types.JDBCSQLTypeInfo;
-import org.teiid.core.types.Transform;
-import org.teiid.core.types.TransformationException;
public class TestDataTypeManager {
- private void helpDetermineDataType(Object value, Class expectedClass) {
- Class actualClass = DataTypeManager.determineDataTypeClass(value);
+ private void helpDetermineDataType(Object value, Class<?> expectedClass) {
+ Class<?> actualClass = DataTypeManager.determineDataTypeClass(value);
assertNotNull("Should never receive null when determining data type of object: " + value); //$NON-NLS-1$
assertEquals("Mismatch in expected and actual MetaMatrix type class for [" + value + "]: ", expectedClass, actualClass); //$NON-NLS-1$ //$NON-NLS-2$
}
@@ -81,19 +75,17 @@
/*timestamp*/ { 'I','N','N','N','N','N','N','N','N','N','N','C','C','O','I','N','N','N' },
/*object*/ { 'C','C','C','C','C','C','C','C','C','C','C','C','C','C','O','C','C','C' },
/*blob*/ { 'N','N','N','N','N','N','N','N','N','N','N','N','N','N','I','O','N','N' },
- /*clob*/ { 'C','N','N','N','N','N','N','N','N','N','N','N','N','N','I','N','O','C' },
- /*xml*/ { 'C','N','N','N','N','N','N','N','N','N','N','N','N','N','I','N','C','O' }
+ /*clob*/ { 'C','N','N','N','N','N','N','N','N','N','N','N','N','N','I','N','O','N' },
+ /*xml*/ { 'C','N','N','N','N','N','N','N','N','N','N','N','N','N','I','N','N','O' }
};
// ################################## ACTUAL TESTS ################################
@Test public void testTypeMappings() {
- Set dataTypeNames = DataTypeManager.getAllDataTypeNames();
- Iterator iter = dataTypeNames.iterator();
- while(iter.hasNext()) {
- String dataTypeName = (String) iter.next();
- Class dataTypeClass = DataTypeManager.getDataTypeClass(dataTypeName);
+ Set<String> dataTypeNames = DataTypeManager.getAllDataTypeNames();
+ for (String dataTypeName : dataTypeNames) {
+ Class<?> dataTypeClass = DataTypeManager.getDataTypeClass(dataTypeName);
assertNotNull("Data type class was null for type " + dataTypeName, dataTypeClass); //$NON-NLS-1$
String dataTypeName2 = DataTypeManager.getDataTypeName(dataTypeClass);
assertEquals("Name to class to name not equals: ", dataTypeName, dataTypeName2); //$NON-NLS-1$
@@ -141,15 +133,9 @@
}
@Test public void testCheckAllConversions() {
- Set allTypes = DataTypeManager.getAllDataTypeNames();
- Iterator srcIter = allTypes.iterator();
- while(srcIter.hasNext()) {
- String src = (String) srcIter.next();
-
- Iterator tgtIter = allTypes.iterator();
- while(tgtIter.hasNext()) {
- String tgt = (String) tgtIter.next();
-
+ Set<String> allTypes = DataTypeManager.getAllDataTypeNames();
+ for (String src : allTypes) {
+ for (String tgt : allTypes) {
boolean isImplicit = DataTypeManager.isImplicitConversion(src, tgt);
boolean isExplicit = DataTypeManager.isExplicitConversion(src, tgt);
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/datatypes.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/datatypes.xml 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/datatypes.xml 2010-06-15 16:49:28 UTC (rev 2233)
@@ -275,7 +275,9 @@
<entry>string</entry>
<entry>clob</entry>
<entry>char, boolean, byte, short, integer, long,
- biginteger, float, double, bigdecimal, xml</entry>
+ biginteger, float, double, bigdecimal, xml<footnote>
+ <para>See also <link linkend="xmlparse">XMLPARSE</link></para>
+ </footnote></entry>
</row>
<row>
<entry>char</entry>
@@ -342,12 +344,14 @@
<row>
<entry>clob</entry>
<entry></entry>
- <entry>string, xml</entry>
+ <entry>string</entry>
</row>
<row>
<entry>xml</entry>
<entry></entry>
- <entry>string, clob</entry>
+ <entry>string<footnote>
+ <para>See also <link linkend="xmlserialize">XMLSERIALIZE</link></para>
+ </footnote></entry>
</row>
</tbody>
</tgroup>
Modified: trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
===================================================================
--- trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2010-06-15 16:49:28 UTC (rev 2233)
@@ -2066,12 +2066,12 @@
</entry>
</row>
<row>
- <entry>
+ <entry id="xmlserialize">
<para><code>XMLSERIALIZE((DOCUMENT|CONTENT) exp [AS datatype])</code></para>
</entry>
<entry>
- <para>Returns a character type representation of the exp.
- Only a character type (string, varchar, clob) may be specified as the datatype.
+ <para>Returns a character type representation of the exp expression.
+ Only a character type (string, clob) may be specified as the datatype.
If DOCUMENT is specified and the xml is not a valid document or fragment, then an exception is raised.
</para>
</entry>
@@ -2080,6 +2080,22 @@
</para>
</entry>
</row>
+ <row>
+ <entry id="xmlparse">
+ <para><code>XMLPARSE((DOCUMENT|CONTENT) exp [WELLFORMED])</code></para>
+ </entry>
+ <entry>
+ <para>Returns an XML type representation of the exp expression. If DOCIMENT is specfied then the expression must have a single
+ root element and may or may not contain an XML declaration.</para>
+ <para>
+ If WELLFORMED is specified then validation is skipped; this is especially useful for CLOB and BLOB known to already be valid.
+ </para>
+ </entry>
+ <entry>
+ <para>Exp in {string, clob, blob}. Return value is xml.
+ </para>
+ </entry>
+ </row>
</tbody>
</tgroup>
</informaltable>
Modified: trunk/engine/src/main/java/org/teiid/common/buffer/FileStore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/FileStore.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/FileStore.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -27,14 +27,12 @@
import java.io.OutputStream;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
-import java.util.Arrays;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Set;
import org.teiid.core.TeiidComponentException;
-
public abstract class FileStore {
private static ReferenceQueue<Object> QUEUE = new ReferenceQueue<Object>();
@@ -94,14 +92,18 @@
}
}
+ public byte[] getBuffer() {
+ return buffer;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
public boolean bytesWritten() {
return bytesWritten;
}
- public byte toByteArray()[] {
- return Arrays.copyOf(buffer, count);
- }
-
@Override
public void close() throws IOException {
if (bytesWritten) {
Modified: trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -58,7 +58,6 @@
import org.teiid.core.types.SQLXMLImpl;
import org.teiid.core.types.SourceTransform;
import org.teiid.core.types.StandardXMLTranslator;
-import org.teiid.core.types.Streamable;
import org.teiid.core.types.XMLType;
import org.teiid.core.util.Assertion;
import org.teiid.logging.LogConstants;
@@ -376,7 +375,7 @@
StandardXMLTranslator sxt = new StandardXMLTranslator(value);
SQLXMLImpl sqlxml;
try {
- sqlxml = XMLUtil.saveToBufferManager(BufferManagerImpl.this, sxt, Streamable.STREAMING_BATCH_SIZE_IN_BYTES);
+ sqlxml = XMLUtil.saveToBufferManager(BufferManagerImpl.this, sxt);
} catch (TeiidComponentException e) {
throw new TeiidRuntimeException(e);
} catch (TeiidProcessingException e) {
@@ -385,7 +384,6 @@
return new XMLType(sqlxml);
}
});
- XMLUtil.setBufferManager(this);
}
@Override
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/ByteLobChunkStream.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/ByteLobChunkStream.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/ByteLobChunkStream.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -35,7 +35,7 @@
* A wrapper class, given a InputStream object can convert a underlying
* stream into sequence of ByteLobChunk objects of given chunk size.
*/
-public class ByteLobChunkStream implements LobChunkProducer {
+public class ByteLobChunkStream implements LobChunkProducer {
private PushbackInputStream stream;
private int chunkSize;
private boolean closed;
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/LobWorkItem.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/LobWorkItem.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/LobWorkItem.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -121,7 +121,7 @@
try {
if (streamable instanceof XMLType) {
XMLType xml = (XMLType)streamable;
- return new ByteLobChunkStream(new ReaderInputStream(xml.getCharacterStream(), Charset.forName(Streamable.ENCODING)), chunkSize);
+ return new ByteLobChunkStream(xml.getBinaryStream(), chunkSize);
}
else if (streamable instanceof ClobType) {
ClobType clob = (ClobType)streamable;
Modified: trunk/engine/src/main/java/org/teiid/metadata/TransformationMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/metadata/TransformationMetadata.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/metadata/TransformationMetadata.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -86,6 +86,34 @@
*/
public class TransformationMetadata extends BasicQueryMetadata implements Serializable {
+ private final class VirtualFileInputStreamFactory extends
+ InputStreamFactory {
+ private final VirtualFile f;
+
+ private VirtualFileInputStreamFactory(VirtualFile f) {
+ this.f = f;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return f.openStream();
+ }
+
+ @Override
+ public long getLength() {
+ try {
+ return f.getSize();
+ } catch (IOException e) {
+ }
+ return super.getLength();
+ }
+
+ @Override
+ public void free() throws IOException {
+ f.close();
+ }
+ }
+
public static class Resource {
public Resource(VirtualFile file, boolean visible) {
this.file = file;
@@ -901,13 +929,7 @@
if (f == null) {
return null;
}
- return new ClobImpl(new InputStreamFactory() {
-
- @Override
- public InputStream getInputStream() throws IOException {
- return f.openStream();
- }
- }, -1);
+ return new ClobImpl(new VirtualFileInputStreamFactory(f), -1);
}
public SQLXMLImpl getVDBResourceAsSQLXML(String resourcePath) {
@@ -915,13 +937,7 @@
if (f == null) {
return null;
}
- return new SQLXMLImpl(new InputStreamFactory() {
-
- @Override
- public InputStream getInputStream() throws IOException {
- return f.openStream();
- }
- });
+ return new SQLXMLImpl(new VirtualFileInputStreamFactory(f));
}
public BlobImpl getVDBResourceAsBlob(String resourcePath) {
@@ -929,18 +945,7 @@
if (f == null) {
return null;
}
- InputStreamFactory isf = new InputStreamFactory() {
-
- @Override
- public InputStream getInputStream() throws IOException {
- return f.openStream();
- }
- };
- try {
- isf.setLength(f.getSize());
- } catch (IOException e) {
- }
- return new BlobImpl(isf);
+ return new BlobImpl(new VirtualFileInputStreamFactory(f));
}
private VirtualFile getFile(String resourcePath) {
Modified: trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -22,11 +22,19 @@
package org.teiid.query.eval;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.sql.Blob;
+import java.sql.Clob;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -44,13 +52,18 @@
import org.teiid.core.ComponentNotFoundException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
+import org.teiid.core.types.BaseLob;
+import org.teiid.core.types.ClobImpl;
+import org.teiid.core.types.ClobType;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.types.InputStreamFactory;
+import org.teiid.core.types.SQLXMLImpl;
import org.teiid.core.types.Sequencable;
+import org.teiid.core.types.Streamable;
import org.teiid.core.types.TransformationException;
import org.teiid.core.types.XMLType;
import org.teiid.core.types.XMLType.Type;
import org.teiid.core.types.basic.StringToSQLXMLTransform;
-import org.teiid.core.util.Assertion;
import org.teiid.core.util.EquivalenceUtil;
import org.teiid.query.QueryPlugin;
import org.teiid.query.function.FunctionDescriptor;
@@ -90,6 +103,7 @@
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLForest;
import org.teiid.query.sql.symbol.XMLNamespaces;
+import org.teiid.query.sql.symbol.XMLParse;
import org.teiid.query.sql.symbol.XMLQuery;
import org.teiid.query.sql.symbol.XMLSerialize;
import org.teiid.query.sql.symbol.XMLNamespaces.NamespaceItem;
@@ -103,7 +117,51 @@
public class Evaluator {
- public static class NameValuePair<T> {
+ private final class SequenceReader extends Reader {
+ private LinkedList<Reader> readers;
+ private Reader current = null;
+
+ public SequenceReader(LinkedList<Reader> readers) {
+ this.readers = readers;
+ }
+
+ @Override
+ public void close() throws IOException {
+ for (Reader reader : readers) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+
+ }
+ }
+ }
+
+ @Override
+ public int read(char[] cbuf, int off, int len)
+ throws IOException {
+ if (current == null && !readers.isEmpty()) {
+ current = readers.removeFirst();
+ }
+ if (current == null) {
+ return -1;
+ }
+ int read = current.read(cbuf, off, len);
+ if (read == -1) {
+ current.close();
+ current = null;
+ read = 0;
+ }
+ if (read < len) {
+ int nextRead = read(cbuf, off + read, len - read);
+ if (nextRead > 0) {
+ read += nextRead;
+ }
+ }
+ return read;
+ }
+ }
+
+ public static class NameValuePair<T> {
public String name;
public T value;
@@ -140,13 +198,13 @@
this.dataMgr = dataMgr;
}
- public boolean evaluate(Criteria criteria, List tuple)
+ public boolean evaluate(Criteria criteria, List<?> tuple)
throws CriteriaEvaluationException, BlockedException, TeiidComponentException {
return Boolean.TRUE.equals(evaluateTVL(criteria, tuple));
}
- public Boolean evaluateTVL(Criteria criteria, List tuple)
+ public Boolean evaluateTVL(Criteria criteria, List<?> tuple)
throws CriteriaEvaluationException, BlockedException, TeiidComponentException {
if(criteria instanceof CompoundCriteria) {
@@ -170,7 +228,7 @@
}
}
- public Boolean evaluate(CompoundCriteria criteria, List tuple)
+ public Boolean evaluate(CompoundCriteria criteria, List<?> tuple)
throws CriteriaEvaluationException, BlockedException, TeiidComponentException {
List subCrits = criteria.getCriteria();
@@ -194,7 +252,7 @@
return result;
}
- public Boolean evaluate(NotCriteria criteria, List tuple)
+ public Boolean evaluate(NotCriteria criteria, List<?> tuple)
throws CriteriaEvaluationException, BlockedException, TeiidComponentException {
Criteria subCrit = criteria.getCriteria();
@@ -208,7 +266,7 @@
return Boolean.TRUE;
}
- public Boolean evaluate(CompareCriteria criteria, List tuple)
+ public Boolean evaluate(CompareCriteria criteria, List<?> tuple)
throws CriteriaEvaluationException, BlockedException, TeiidComponentException {
// Evaluate left expression
@@ -265,7 +323,7 @@
return ((Comparable<Object>)leftValue).compareTo(rightValue);
}
- public Boolean evaluate(MatchCriteria criteria, List tuple)
+ public Boolean evaluate(MatchCriteria criteria, List<?> tuple)
throws CriteriaEvaluationException, BlockedException, TeiidComponentException {
boolean result = false;
@@ -330,7 +388,7 @@
}
}
- private Boolean evaluate(AbstractSetCriteria criteria, List tuple)
+ private Boolean evaluate(AbstractSetCriteria criteria, List<?> tuple)
throws CriteriaEvaluationException, BlockedException, TeiidComponentException {
// Evaluate expression
@@ -372,7 +430,7 @@
throw new CriteriaEvaluationException(e, e.getMessage());
}
} else {
- Assertion.failed("unknown set criteria type"); //$NON-NLS-1$
+ throw new AssertionError("unknown set criteria type"); //$NON-NLS-1$
}
while(valueIter.hasNext()) {
Object possibleValue = valueIter.next();
@@ -403,7 +461,7 @@
return Boolean.valueOf(criteria.isNegated());
}
- public boolean evaluate(IsNullCriteria criteria, List tuple)
+ public boolean evaluate(IsNullCriteria criteria, List<?> tuple)
throws CriteriaEvaluationException, BlockedException, TeiidComponentException {
// Evaluate expression
@@ -417,7 +475,7 @@
return (value == null ^ criteria.isNegated());
}
- private Boolean evaluate(SubqueryCompareCriteria criteria, List tuple)
+ private Boolean evaluate(SubqueryCompareCriteria criteria, List<?> tuple)
throws CriteriaEvaluationException, BlockedException, TeiidComponentException {
// Evaluate expression
@@ -528,7 +586,7 @@
return result;
}
- public boolean evaluate(ExistsCriteria criteria, List tuple)
+ public boolean evaluate(ExistsCriteria criteria, List<?> tuple)
throws BlockedException, TeiidComponentException, CriteriaEvaluationException {
ValueIterator valueIter;
@@ -543,7 +601,7 @@
return false;
}
- public Object evaluate(Expression expression, List tuple)
+ public Object evaluate(Expression expression, List<?> tuple)
throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
try {
@@ -553,7 +611,7 @@
}
}
- private Object internalEvaluate(Expression expression, List tuple)
+ private Object internalEvaluate(Expression expression, List<?> tuple)
throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
if(expression instanceof SingleElementSymbol) {
@@ -600,13 +658,88 @@
return evaluateXMLQuery(tuple, (XMLQuery)expression);
} else if (expression instanceof QueryString) {
return evaluateQueryString(tuple, (QueryString)expression);
+ } else if (expression instanceof XMLParse){
+ return evaluateXMLParse(tuple, (XMLParse)expression);
} else {
throw new TeiidComponentException(ErrorMessageKeys.PROCESSOR_0016, QueryPlugin.Util.getString(ErrorMessageKeys.PROCESSOR_0016, expression.getClass().getName()));
}
}
+ private Object evaluateXMLParse(List<?> tuple, final XMLParse xp) throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
+ Object value = internalEvaluate(xp.getExpression(), tuple);
+ if (value == null) {
+ return null;
+ }
+ XMLType.Type type = Type.DOCUMENT;
+ XMLType result = null;
+ try {
+ if (value instanceof String) {
+ String string = (String)value;
+ result = new XMLType(new SQLXMLImpl(string));
+ if (!xp.isWellFormed()) {
+ Reader r = new StringReader(string);
+ type = validate(xp, r);
+ }
+ } else {
+ InputStreamFactory isf = null;
+ Streamable<?> s = (Streamable<?>)value;
+ if (s.getReference() instanceof BaseLob) {
+ BaseLob baseLob = (BaseLob)s.getReference();
+ isf = baseLob.getStreamFactory();
+ } else {
+ if (s instanceof Clob) {
+ isf = new InputStreamFactory.ClobInputStreamFactory((Clob)s.getReference());
+ } else {
+ isf = new InputStreamFactory.BlobInputStreamFactory((Blob)s.getReference());
+ }
+ }
+ result = new XMLType(new SQLXMLImpl(isf));
+ if (!xp.isWellFormed()) {
+ String encoding = null;
+ Reader r = null;
+ if (s instanceof Clob) {
+ r = isf.getCharacterStream();
+ } else {
+ encoding = XMLType.getEncoding(result); //look for the xml declaration
+ if (encoding == null) {
+ encoding = "UTF-8"; //$NON-NLS-1$
+ }
+ r = new InputStreamReader(isf.getInputStream(), encoding);
+ }
+ type = validate(xp, r);
+ if (encoding != null) {
+ isf.setEncoding(encoding);
+ }
+ }
+ }
+ } catch (TransformationException e) {
+ throw new ExpressionEvaluationException(e, e.getMessage());
+ } catch (IOException e) {
+ throw new ExpressionEvaluationException(e, e.getMessage());
+ } catch (SQLException e) {
+ throw new ExpressionEvaluationException(e, e.getMessage());
+ }
+ if (!xp.isDocument()) {
+ type = Type.CONTENT;
+ }
+ result.setType(type);
+ return result;
+ }
+
+ private Type validate(final XMLParse xp, Reader r)
+ throws TransformationException {
+ if (!xp.isDocument()) {
+ LinkedList<Reader> readers = new LinkedList<Reader>();
+ readers.add(new StringReader("<r>")); //$NON-NLS-1$
+ readers.add(r);
+ readers.add(new StringReader("</r>")); //$NON-NLS-1$
+ r = new SequenceReader(readers);
+ }
+ return StringToSQLXMLTransform.isXml(r);
+ }
+
//TODO: exception if length is too long?
- private Object evaluateQueryString(List tuple, QueryString queryString)
+ private Object evaluateQueryString(List<?> tuple, QueryString queryString)
throws ExpressionEvaluationException, BlockedException,
TeiidComponentException {
Evaluator.NameValuePair<Object>[] pairs = getNameValuePairs(tuple, queryString.getArgs(), false);
@@ -634,7 +767,7 @@
return result.toString();
}
- private Object evaluateXMLQuery(List tuple, XMLQuery xmlQuery)
+ private Object evaluateXMLQuery(List<?> tuple, XMLQuery xmlQuery)
throws BlockedException, TeiidComponentException,
FunctionExecutionException {
boolean emptyOnEmpty = true;
@@ -643,7 +776,7 @@
}
try {
SequenceIterator iter = evaluateXQuery(xmlQuery.getXQueryExpression(), xmlQuery.getPassing(), tuple);
- return xmlQuery.getXQueryExpression().createXMLType(iter, emptyOnEmpty);
+ return xmlQuery.getXQueryExpression().createXMLType(iter, this.context.getBufferManager(), emptyOnEmpty);
} catch (TeiidProcessingException e) {
throw new FunctionExecutionException(e, QueryPlugin.Util.getString("Evaluator.xmlquery", e.getMessage())); //$NON-NLS-1$
} catch (XPathException e) {
@@ -651,7 +784,7 @@
}
}
- private Object evaluateXMLSerialize(List tuple, XMLSerialize xs)
+ private Object evaluateXMLSerialize(List<?> tuple, XMLSerialize xs)
throws ExpressionEvaluationException, BlockedException,
TeiidComponentException, FunctionExecutionException {
XMLType value = (XMLType) internalEvaluate(xs.getExpression(), tuple);
@@ -660,14 +793,14 @@
}
try {
if (!xs.isDocument()) {
- return DataTypeManager.transformValue(value, xs.getType());
+ return serialize(xs, value);
}
if (value.getType() == Type.UNKNOWN) {
Type type = StringToSQLXMLTransform.isXml(value.getCharacterStream());
value.setType(type);
}
if (value.getType() == Type.DOCUMENT || value.getType() == Type.ELEMENT) {
- return DataTypeManager.transformValue(value, xs.getType());
+ return serialize(xs, value);
}
} catch (SQLException e) {
throw new FunctionExecutionException(e, e.getMessage());
@@ -677,7 +810,22 @@
throw new FunctionExecutionException(QueryPlugin.Util.getString("Evaluator.xmlserialize")); //$NON-NLS-1$
}
- private Object evaluateXMLForest(List tuple, XMLForest function)
+ private Object serialize(XMLSerialize xs, XMLType value)
+ throws SQLException, TransformationException {
+ if (xs.getType() == DataTypeManager.DefaultDataClasses.STRING) {
+ return DataTypeManager.transformValue(value, xs.getType());
+ }
+ InputStreamFactory isf = null;
+ if (value.getReference() instanceof BaseLob) {
+ BaseLob baseLob = (BaseLob)value.getReference();
+ isf = baseLob.getStreamFactory();
+ } else {
+ isf = new InputStreamFactory.SQLXMLInputStreamFactory(value.getReference());
+ }
+ return new ClobType(new ClobImpl(isf, -1));
+ }
+
+ private Object evaluateXMLForest(List<?> tuple, XMLForest function)
throws ExpressionEvaluationException, BlockedException,
TeiidComponentException, FunctionExecutionException {
List<DerivedColumn> args = function.getArgs();
@@ -690,7 +838,7 @@
}
}
- private Object evaluateXMLElement(List tuple, XMLElement function)
+ private Object evaluateXMLElement(List<?> tuple, XMLElement function)
throws ExpressionEvaluationException, BlockedException,
TeiidComponentException, FunctionExecutionException {
List<Expression> content = function.getContent();
@@ -724,7 +872,7 @@
return xquery.evaluateXQuery(contextItem, parameters);
}
- private Evaluator.NameValuePair<Object>[] getNameValuePairs(List tuple, List<DerivedColumn> args, boolean xmlNames)
+ private Evaluator.NameValuePair<Object>[] getNameValuePairs(List<?> tuple, List<DerivedColumn> args, boolean xmlNames)
throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
Evaluator.NameValuePair<Object>[] nameValuePairs = new Evaluator.NameValuePair[args.size()];
for (int i = 0; i < args.size(); i++) {
@@ -755,7 +903,7 @@
return nameValuePairs;
}
- private Object evaluate(CaseExpression expr, List tuple)
+ private Object evaluate(CaseExpression expr, List<?> tuple)
throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
Object exprVal = internalEvaluate(expr.getExpression(), tuple);
for (int i = 0; i < expr.getWhenCount(); i++) {
@@ -769,7 +917,7 @@
return null;
}
- private Object evaluate(SearchedCaseExpression expr, List tuple)
+ private Object evaluate(SearchedCaseExpression expr, List<?> tuple)
throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
for (int i = 0; i < expr.getWhenCount(); i++) {
try {
@@ -786,7 +934,7 @@
return null;
}
- private Object evaluate(Function function, List tuple)
+ private Object evaluate(Function function, List<?> tuple)
throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
// Get function based on resolved function info
@@ -837,7 +985,7 @@
return result;
}
- private Object evaluate(ScalarSubquery scalarSubquery, List tuple)
+ private Object evaluate(ScalarSubquery scalarSubquery, List<?> tuple)
throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
Object result = null;
@@ -858,7 +1006,7 @@
return result;
}
- protected ValueIterator evaluateSubquery(SubqueryContainer container, List tuple)
+ protected ValueIterator evaluateSubquery(SubqueryContainer container, List<?> tuple)
throws TeiidProcessingException, BlockedException, TeiidComponentException {
throw new UnsupportedOperationException("Subquery evaluation not possible with a base Evaluator"); //$NON-NLS-1$
}
Modified: trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/function/FunctionDescriptor.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -267,6 +267,12 @@
}
result = DataTypeManager.convertToRuntimeType(result);
result = DataTypeManager.transformValue(result, getReturnType());
+ if (result instanceof String) {
+ String s = (String)result;
+ if (s.length() > DataTypeManager.MAX_STRING_LENGTH) {
+ return s.substring(0, DataTypeManager.MAX_STRING_LENGTH);
+ }
+ }
return result;
} catch(InvocationTargetException e) {
throw new FunctionExecutionException(e.getTargetException(), ErrorMessageKeys.FUNCTION_0003, QueryPlugin.Util.getString(ErrorMessageKeys.FUNCTION_0003, getName()));
Modified: trunk/engine/src/main/java/org/teiid/query/function/source/XMLSystemFunctions.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/function/source/XMLSystemFunctions.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/function/source/XMLSystemFunctions.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -65,10 +65,10 @@
import org.teiid.api.exception.query.FunctionExecutionException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
+import org.teiid.core.types.ClobImpl;
import org.teiid.core.types.ClobType;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.SQLXMLImpl;
-import org.teiid.core.types.Streamable;
import org.teiid.core.types.TransformationException;
import org.teiid.core.types.XMLTranslator;
import org.teiid.core.types.XMLType;
@@ -113,7 +113,7 @@
final Transformer transformer = factory.newTransformer(styleSource);
//this creates a non-validated sqlxml - it may not be valid xml/root-less xml
- SQLXML result = XMLUtil.saveToBufferManager(context.getBufferManager(), new XMLTranslator() {
+ SQLXMLImpl result = XMLUtil.saveToBufferManager(context.getBufferManager(), new XMLTranslator() {
@Override
public void translate(Writer writer) throws TransformerException {
@@ -121,8 +121,8 @@
// Feed the resultant I/O stream into the XSLT processor
transformer.transform(xmlParam, new StreamResult(writer));
}
- }, Streamable.STREAMING_BATCH_SIZE_IN_BYTES);
- return DataTypeManager.transformValue(new XMLType(result), DataTypeManager.DefaultDataClasses.CLOB);
+ });
+ return new ClobType(new ClobImpl(result.getStreamFactory(), -1));
} finally {
Util.closeSource(styleSource);
Util.closeSource(xmlSource);
@@ -160,7 +160,7 @@
throw new TransformerException(e);
}
}
- }, context.getStreamingBatchSize()));
+ }));
result.setType(Type.CONTENT);
return result;
}
@@ -191,7 +191,7 @@
}
}
- }, context.getStreamingBatchSize()));
+ }));
result.setType(Type.ELEMENT);
return result;
}
@@ -228,6 +228,27 @@
}
public static XMLType xmlConcat(CommandContext context, final XMLType xml, final Object... other) throws TeiidComponentException, TeiidProcessingException {
+ //determine if there is just a single xml value and return it
+ XMLType singleValue = xml;
+ XMLType.Type type = null;
+ for (Object object : other) {
+ if (object != null) {
+ if (singleValue != null) {
+ type = Type.CONTENT;
+ break;
+ }
+ if (object instanceof XMLType) {
+ singleValue = (XMLType)object;
+ } else {
+ type = Type.CONTENT;
+ break;
+ }
+ }
+ }
+ if (type == null) {
+ return singleValue;
+ }
+
XMLType result = new XMLType(XMLUtil.saveToBufferManager(context.getBufferManager(), new XMLTranslator() {
@Override
@@ -245,7 +266,7 @@
throw new TransformerException(e);
}
}
- }, context.getStreamingBatchSize()));
+ }));
result.setType(Type.CONTENT);
return result;
}
@@ -280,11 +301,11 @@
}
}
- static void convertValue(Writer writer, XMLEventWriter eventWriter, XMLEventFactory eventFactory, Object object) throws IOException,
+ static int convertValue(Writer writer, XMLEventWriter eventWriter, XMLEventFactory eventFactory, Object object) throws IOException,
FactoryConfigurationError, XMLStreamException,
TransformerException {
if (object == null) {
- return;
+ return 0;
}
Reader r = null;
try {
@@ -308,6 +329,7 @@
r.close();
}
}
+ return 1;
//TODO: blob - with base64 encoding
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -142,7 +142,7 @@
continue;
}
if (proColumn.getSymbol().getType() == DataTypeManager.DefaultDataClasses.XML) {
- XMLType value = table.getXQueryExpression().createXMLType(pathIter.getAnother(), false);
+ XMLType value = table.getXQueryExpression().createXMLType(pathIter.getAnother(), this.getBufferManager(), false);
tuple.add(value);
continue;
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/xml/DocumentInProgress.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/xml/DocumentInProgress.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/processor/xml/DocumentInProgress.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -22,95 +22,326 @@
package org.teiid.query.processor.xml;
+import java.util.Iterator;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+
+import net.sf.saxon.TransformerFactoryImpl;
+
import org.teiid.common.buffer.FileStore;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.types.SQLXMLImpl;
+import org.teiid.logging.LogManager;
+import org.teiid.logging.MessageLevel;
+import org.teiid.query.mapping.xml.MappingNodeConstants;
+import org.teiid.query.processor.xml.XMLUtil.FileStoreInputStreamFactory;
import org.xml.sax.SAXException;
/**
- * <p>This represents a document in construction. It maintains a reference
- * to the current XML element being worked on, although the nature of that
- * reference is completely hidden from the user. This allows the nastiness
- * of creating the document using some document model to be hidden from the
- * user.</p>
+ * This class is used to build XML document and stream the output as
+ * chunks. The class holds one chunk of the document in memory at one time.
*/
-public interface DocumentInProgress {
+public class DocumentInProgress {
+ private TransformerHandler handler;
+ private Transformer transformer;
+ private Element currentParent;
+ private Element currentObject;
+ private boolean finished;
+ private String documentEncoding = MappingNodeConstants.Defaults.DEFAULT_DOCUMENT_ENCODING;
+ private boolean isFormatted = MappingNodeConstants.Defaults.DEFAULT_FORMATTED_DOCUMENT.booleanValue();
+ private SQLXMLImpl xml;
+
+ public DocumentInProgress(FileStore store, String encoding) throws TeiidComponentException{
+ final FileStoreInputStreamFactory fsisf = new FileStoreInputStreamFactory(store, encoding);
+ this.xml = new SQLXMLImpl(fsisf);
+ SAXTransformerFactory factory = new TransformerFactoryImpl();
+ try {
+ //SAX2.0 ContentHandler
+ handler = factory.newTransformerHandler();
+ handler.setResult(new StreamResult(fsisf.getOuptStream()));
+ } catch (Exception e) {
+ throw new TeiidComponentException(e);
+ }
+ transformer = handler.getTransformer();
+ }
+
+ public SQLXMLImpl getSQLXML() {
+ return xml;
+ }
+
+ /**
+ * @see org.teiid.query.processor.xml.DocumentInProgress#setDocumentEncoding(java.lang.String)
+ */
+ public void setDocumentEncoding(String documentEncoding) {
+ this.documentEncoding = documentEncoding;
+ }
- // Methods for initializing the document
+ /**
+ * @see org.teiid.query.processor.xml.DocumentInProgress#setDocumentFormat(boolean)
+ */
+ public void setDocumentFormat(boolean isFormatted) {
+ this.isFormatted = isFormatted;
+ }
- /**
- * Sets the document encoding property of the XML document,
- * typically something like <code>UTF-8</code>
- * @param document encoding value
- */
- public void setDocumentEncoding(String documentEncoding);
+ /**
+ * Move to the parent of this element. The parent of this element becomes
+ * the current object. Need to process the current and child object before moving
+ * to the parent.
+ * @throws SAXException
+ * @see org.teiid.query.processor.xml.DocumentInProgress#moveToParent()
+ */
+ public boolean moveToParent() throws SAXException {
+ showState( "moveToParent - TOP" ); //$NON-NLS-1$
+
+ endElement(currentObject);
+
+ //move to parent - if parent is null, then stop processing here
+ if(currentParent == null){
+ return false;
+ }
+
+ showState( "moveToParent - before processWorkingElements, second time" ); //$NON-NLS-1$
+ currentObject = currentParent;
+ currentParent = currentParent.getParent();
+ showState( "moveToParent - BOT" ); //$NON-NLS-1$
+ return true;
+ }
+
+ /**
+ * @see org.teiid.query.processor.xml.DocumentInProgress#moveToLastChild()
+ */
+ public boolean moveToLastChild() {
+ showState( "moveToLastChild - TOP" ); //$NON-NLS-1$
+ currentParent = currentObject;
+ currentObject = null;
+ showState( "moveToLastChild - BOT" ); //$NON-NLS-1$
+ return true;
+ }
- /**
- * Sets whether the document will be formatted in human-readable
- * form (multi-line, with tabs) or compact form (no line breaks
- * or tabs).
- * @param isFormatted true for human-readable form, false for
- * compact form
- */
- public void setDocumentFormat(boolean isFormatted);
+ public boolean addElement(NodeDescriptor descriptor, NodeDescriptor nillableDescriptor){
+ return addElement(descriptor, null, nillableDescriptor);
+ }
+
+ public boolean addElement(NodeDescriptor descriptor, String content){
+ return addElement(descriptor, content, null);
+ }
+
+ private boolean addElement(NodeDescriptor descriptor, String content, NodeDescriptor nillableDescriptor){
+ showState( "addElement(2) - TOP" ); //$NON-NLS-1$
+
+ try{
+ if(currentParent == null){
+ //this is the root element, start document first
+ showState( "addElement(2) - before StartDocument()" ); //$NON-NLS-1$
- // Methods for moving the cursor
+ startDocument();
+ }
+ Element element = makeElement(descriptor);
+ if (element != null){
+ if (content != null) {
+ element.setContent(normalizeText(content, descriptor.getTextNormalizationMode()));
+ //mark the element and its parents to be mandatory
+ markAsNonOptional(element);
+ } else {
+ element.setNillableDescriptor(nillableDescriptor);
+ }
+
+ showState( "addElement(2) - before markAsNonOptional()" ); //$NON-NLS-1$
+
+ endElement(currentObject);
+ currentObject = element;
+ return true;
+ }
+ } catch (SAXException e) {
+ LogManager.logError(org.teiid.logging.LogConstants.CTX_XML_PLAN, e, e.getMessage());
+ return false;
+ }
+ showState( "addElement(2) - BOT" ); //$NON-NLS-1$
+ return false;
+ }
- public boolean moveToParent() throws SAXException;
-
- public boolean moveToLastChild();
-
- // Methods for adding data
-
- /**
- * Add an element for the given NodeDescriptor.
- * @param descriptor NodeDescriptor of the element
- * @return whether operation was a success or not
- */
- boolean addElement(NodeDescriptor descriptor, NodeDescriptor nillableDescriptor);
+ private void endElement(Element element) throws SAXException {
+ showState( "endElement(2) - TOP" ); //$NON-NLS-1$
+
+ if (element == null) {
+ return;
+ }
+
+ if (element.isOptional()) {
+ if (element.getParent() != null) {
+ element.getParent().getChildren().remove(element);
+ }
+ return;
+ }
+
+ NodeDescriptor nillableDescriptor = element.getNillableDescriptor();
+
+ if (nillableDescriptor != null) {
+ addAttribute(nillableDescriptor, nillableDescriptor.getDefaultValue(), element);
+ }
+
+ // Optional parents are in control of when their children are emitted.
+ if (element.hadOptionalParent()) {
+ return;
+ }
+
+ startElement(element);
+ processChildren(element);
+ element.endElement();
+
+ if (element.getParent() != null) {
+ element.getParent().getChildren().remove(element);
+ }
+ showState( "endElement(2) - BOT" ); //$NON-NLS-1$
+ }
+
+ private void startElement(Element element) throws SAXException {
+ Element parent = element.getParent();
+ while (parent != null && !parent.isElementStarted()) {
+ parent.setNillableDescriptor(null);
+ startElement(parent);
+ }
+ element.startElement();
+ }
+
+ private void processChildren(Element element) throws SAXException {
+
+ for (Iterator i = element.getChildren().iterator(); i.hasNext();) {
+ Element child = (Element)i.next();
+ i.remove();
+
+ child.startElement();
+ processChildren(child);
+ child.endElement();
+ }
+ }
- /**
- * Add an element with content for the given NodeDescriptor.
- * If the content is either a null or an empty String, use the other
- * {@link #addElement(NodeDescriptor) addElement}
- * method.
- * @param descriptor NodeDescriptor of the element
- * @param content Content of the element
- * @return whether operation was a success or not
- */
- public boolean addElement(NodeDescriptor descriptor, String content);
+ private void markAsNonOptional(Element element) {
- /**
- * Add an attribute with content for the given NodeDescriptor.
- * @param descriptor NodeDescriptor of the attribute
- * @param attributeValue String content of the attribute, this must be a
- * non-null, non-empty String. Otherwise, no attribute will be added.
- * @return whether operation was a success or not
- */
- public boolean addAttribute(NodeDescriptor descriptor, String attributeValue);
+ while(element != null){
+ element.setOptional(false);
+ element = element.getParent();
+ }
+ }
+
+ public boolean addAttribute(NodeDescriptor descriptor, String attributeValue, Element element){
+ element.setAttribute(descriptor, normalizeText(attributeValue,descriptor.getTextNormalizationMode()));
+
+ if (!descriptor.isOptional()){
+ //mark the element and its parents to be mandatory
+ markAsNonOptional(element);
+ }
+ return true;
+ }
/**
- * Adds a comment to the current document node
- * @param commentText text of the comment
- * @return whether operation was a success or not
+ * @see org.teiid.query.processor.xml.DocumentInProgress#addAttribute(java.lang.String, java.lang.String, java.lang.String, boolean)
*/
- public boolean addComment(String commentText);
+ public boolean addAttribute(NodeDescriptor descriptor, String attributeValue){
+ return addAttribute(descriptor, attributeValue, currentParent);
+ }
+ /**
+ * @throws TeiidComponentException
+ * @see org.teiid.query.processor.xml.DocumentInProgress#addComment(java.lang.String)
+ */
+ public boolean addComment(String commentText) {
+ currentParent.setComment(commentText);
+ return true;
+ }
- /**
- * This flag indicates the document is finished and requires no more processing.
- * @see #markAsFinished
+ /**
+ * @see org.teiid.query.processor.xml.DocumentInProgress#isFinished()
+ */
+ public boolean isFinished() {
+ return finished;
+ }
+
+ /**
+ * @see org.teiid.query.processor.xml.DocumentInProgress#markAsFinished()
+ */
+ public void markAsFinished() throws TeiidComponentException{
+ try {
+ endDocument();
+ } catch (SAXException e) {
+ throw new TeiidComponentException(e);
+ }
+ finished = true;
+ }
+
+ private Element makeElement(NodeDescriptor descripter) {
+ showState( "makeElement - TOP" ); //$NON-NLS-1$
+ Element element = new Element(descripter, handler);
+ element.setParent(currentParent);
+ if (currentParent != null) {
+ currentParent.addChild(element);
+ }
+ showState( "makeElement - BOT" ); //$NON-NLS-1$
+ return element;
+ }
+
+ private void startDocument() throws SAXException{
+ showState( "startDocument - TOP" ); //$NON-NLS-1$
+ transformer.setOutputProperty(OutputKeys.ENCODING, documentEncoding);
+ if(isFormatted){
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");//$NON-NLS-1$
+ }
+ handler.startDocument();
+ showState( "startDocument - BOT" ); //$NON-NLS-1$
+ }
+
+ private void endDocument() throws SAXException{
+ //special case: only one root element
+ endElement(currentObject);
+ handler.endDocument();
+ }
+
+ /**
+ * @param content
+ * @param textNormalizationMode
+ * preserve No normalization is done, the value is not changed for element content
+ * replace All occurrences of #x9 (tab), #xA (line feed) and #xD (carriage return) are replaced with #x20 (space)
+ * collapse After the processing implied by replace, contiguous sequences of #x20's are collapsed to a single #x20, and leading and trailing #x20's are removed.
+ *
+ * @return
+ * @since 4.3
+
*/
- public boolean isFinished();
+ public static String normalizeText(String content, String textNormalizationMode) {
+ String result = content;
+ String singleSpace = " "; //$NON-NLS-1$
+ if(textNormalizationMode.equalsIgnoreCase(MappingNodeConstants.NORMALIZE_TEXT_REPLACE)) {
+ result = result.replaceAll("\\s", singleSpace); //$NON-NLS-1$
+ }else if(textNormalizationMode.equalsIgnoreCase(MappingNodeConstants.NORMALIZE_TEXT_COLLAPSE)){
+ result = result.replaceAll("\\s+", singleSpace); //$NON-NLS-1$
+ result = result.trim();
+ }
+ return result;
+ }
+
- /**
- * This marks the document as finished, requiring no more processing. (It will not,
- * however, prevent any more processing from being done.)
- * @throws TeiidComponentException if there is any problem ending the document
- * @see #isFinished
- */
- public void markAsFinished() throws TeiidComponentException;
+ private void showState( String sOccasion ) {
+
+ if (LogManager.isMessageToBeRecorded(org.teiid.logging.LogConstants.CTX_XML_PLAN, MessageLevel.TRACE)) {
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"\n [showState] State Vars at: " + sOccasion} ); //$NON-NLS-1$
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] currentParent: " + currentParent} ); //$NON-NLS-1$
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] currentObject: " + currentObject} ); //$NON-NLS-1$
+
+ if ( currentObject != null ) {
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] currentObject.getNillableDescriptor(): " + currentObject.getNillableDescriptor()}); //$NON-NLS-1$
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] workingElements: " + currentObject.getChildren()}); //$NON-NLS-1$
+ }
+ if ( currentParent != null ) {
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] currentParent.getParent(): " + currentParent.getParent()}); //$NON-NLS-1$
+ } else {
+ LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] currentParent.getParent(): is NULL "}); //$NON-NLS-1$
+ }
+ }
+ }
- public FileStore getFileStore();
-
}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/xml/InitializeDocumentInstruction.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/xml/InitializeDocumentInstruction.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/processor/xml/InitializeDocumentInstruction.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -84,12 +84,10 @@
// program stack (don't want to start a new doc in the middle of
// recursive processing)
if (!env.isRecursiveProgramInStack()) {
- DocumentInProgress doc = new SAXDocumentInProgress(env.getBufferManager().createFileStore("xml")); //$NON-NLS-1$
+ DocumentInProgress doc = new DocumentInProgress(env.getBufferManager().createFileStore("xml"), encoding); //$NON-NLS-1$
//DocumentInProgress doc = new JDOMDocumentInProgress();
env.setDocumentInProgress(doc);
- doc.setDocumentEncoding(encoding);
-
// Override the xml format flag from the model with
// the format specified with the user's query request, if any.
boolean formatted = this.isFormatted;
Deleted: trunk/engine/src/main/java/org/teiid/query/processor/xml/SAXDocumentInProgress.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/xml/SAXDocumentInProgress.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/processor/xml/SAXDocumentInProgress.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -1,348 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-package org.teiid.query.processor.xml;
-
-import java.io.BufferedOutputStream;
-import java.util.Iterator;
-
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-
-import net.sf.saxon.TransformerFactoryImpl;
-
-import org.teiid.common.buffer.FileStore;
-import org.teiid.core.TeiidComponentException;
-import org.teiid.logging.LogManager;
-import org.teiid.logging.MessageLevel;
-import org.teiid.query.mapping.xml.MappingNodeConstants;
-import org.xml.sax.SAXException;
-
-
-/**
- * This class is used to build XML document and stream the output as
- * chunks. The class holds one chunk of the document in memory at one time.
- */
-public class SAXDocumentInProgress implements DocumentInProgress {
- private TransformerHandler handler;
- private Transformer transformer;
- private Element currentParent;
- private Element currentObject;
- private boolean finished;
- private String documentEncoding = MappingNodeConstants.Defaults.DEFAULT_DOCUMENT_ENCODING;
- private boolean isFormatted = MappingNodeConstants.Defaults.DEFAULT_FORMATTED_DOCUMENT.booleanValue();
- private FileStore store;
-
- public SAXDocumentInProgress(FileStore store) throws TeiidComponentException{
- this.store = store;
- SAXTransformerFactory factory = new TransformerFactoryImpl();
- //TODO use standard jaxp to create factory
- //SAXTransformerFactory factory = (SAXTransformerFactory)TransformerFactory.newInstance();
- try {
- //SAX2.0 ContentHandler
- handler = factory.newTransformerHandler();
- handler.setResult(new StreamResult(new BufferedOutputStream(store.createOutputStream())));
- } catch (Exception e) {
- throw new TeiidComponentException(e);
- }
- transformer = handler.getTransformer();
- }
-
- /**
- * @see org.teiid.query.processor.xml.DocumentInProgress#setDocumentEncoding(java.lang.String)
- */
- public void setDocumentEncoding(String documentEncoding) {
- this.documentEncoding = documentEncoding;
- }
-
- /**
- * @see org.teiid.query.processor.xml.DocumentInProgress#setDocumentFormat(boolean)
- */
- public void setDocumentFormat(boolean isFormatted) {
- this.isFormatted = isFormatted;
- }
-
- /**
- * Move to the parent of this element. The parent of this element becomes
- * the current object. Need to process the current and child object before moving
- * to the parent.
- * @throws SAXException
- * @see org.teiid.query.processor.xml.DocumentInProgress#moveToParent()
- */
- public boolean moveToParent() throws SAXException {
- showState( "moveToParent - TOP" ); //$NON-NLS-1$
-
- endElement(currentObject);
-
- //move to parent - if parent is null, then stop processing here
- if(currentParent == null){
- return false;
- }
-
- showState( "moveToParent - before processWorkingElements, second time" ); //$NON-NLS-1$
- currentObject = currentParent;
- currentParent = currentParent.getParent();
- showState( "moveToParent - BOT" ); //$NON-NLS-1$
- return true;
- }
-
- /**
- * @see org.teiid.query.processor.xml.DocumentInProgress#moveToLastChild()
- */
- public boolean moveToLastChild() {
- showState( "moveToLastChild - TOP" ); //$NON-NLS-1$
- currentParent = currentObject;
- currentObject = null;
- showState( "moveToLastChild - BOT" ); //$NON-NLS-1$
- return true;
- }
-
- public boolean addElement(NodeDescriptor descriptor, NodeDescriptor nillableDescriptor){
- return addElement(descriptor, null, nillableDescriptor);
- }
-
- public boolean addElement(NodeDescriptor descriptor, String content){
- return addElement(descriptor, content, null);
- }
-
- private boolean addElement(NodeDescriptor descriptor, String content, NodeDescriptor nillableDescriptor){
- showState( "addElement(2) - TOP" ); //$NON-NLS-1$
-
- try{
- if(currentParent == null){
- //this is the root element, start document first
- showState( "addElement(2) - before StartDocument()" ); //$NON-NLS-1$
-
- startDocument();
- }
- Element element = makeElement(descriptor);
- if (element != null){
- if (content != null) {
- element.setContent(normalizeText(content, descriptor.getTextNormalizationMode()));
- //mark the element and its parents to be mandatory
- markAsNonOptional(element);
- } else {
- element.setNillableDescriptor(nillableDescriptor);
- }
-
- showState( "addElement(2) - before markAsNonOptional()" ); //$NON-NLS-1$
-
- endElement(currentObject);
- currentObject = element;
- return true;
- }
- } catch (SAXException e) {
- LogManager.logError(org.teiid.logging.LogConstants.CTX_XML_PLAN, e, e.getMessage());
- return false;
- }
- showState( "addElement(2) - BOT" ); //$NON-NLS-1$
- return false;
- }
-
- private void endElement(Element element) throws SAXException {
- showState( "endElement(2) - TOP" ); //$NON-NLS-1$
-
- if (element == null) {
- return;
- }
-
- if (element.isOptional()) {
- if (element.getParent() != null) {
- element.getParent().getChildren().remove(element);
- }
- return;
- }
-
- NodeDescriptor nillableDescriptor = element.getNillableDescriptor();
-
- if (nillableDescriptor != null) {
- addAttribute(nillableDescriptor, nillableDescriptor.getDefaultValue(), element);
- }
-
- // Optional parents are in control of when their children are emitted.
- if (element.hadOptionalParent()) {
- return;
- }
-
- startElement(element);
- processChildren(element);
- element.endElement();
-
- if (element.getParent() != null) {
- element.getParent().getChildren().remove(element);
- }
- showState( "endElement(2) - BOT" ); //$NON-NLS-1$
- }
-
- private void startElement(Element element) throws SAXException {
- Element parent = element.getParent();
- while (parent != null && !parent.isElementStarted()) {
- parent.setNillableDescriptor(null);
- startElement(parent);
- }
- element.startElement();
- }
-
- private void processChildren(Element element) throws SAXException {
-
- for (Iterator i = element.getChildren().iterator(); i.hasNext();) {
- Element child = (Element)i.next();
- i.remove();
-
- child.startElement();
- processChildren(child);
- child.endElement();
- }
- }
-
- private void markAsNonOptional(Element element) {
-
- while(element != null){
- element.setOptional(false);
- element = element.getParent();
- }
- }
-
- public boolean addAttribute(NodeDescriptor descriptor, String attributeValue, Element element){
- element.setAttribute(descriptor, normalizeText(attributeValue,descriptor.getTextNormalizationMode()));
-
- if (!descriptor.isOptional()){
- //mark the element and its parents to be mandatory
- markAsNonOptional(element);
- }
- return true;
- }
-
- /**
- * @see org.teiid.query.processor.xml.DocumentInProgress#addAttribute(java.lang.String, java.lang.String, java.lang.String, boolean)
- */
- public boolean addAttribute(NodeDescriptor descriptor, String attributeValue){
- return addAttribute(descriptor, attributeValue, currentParent);
- }
-
- /**
- * @throws TeiidComponentException
- * @see org.teiid.query.processor.xml.DocumentInProgress#addComment(java.lang.String)
- */
- public boolean addComment(String commentText) {
- currentParent.setComment(commentText);
- return true;
- }
-
- /**
- * @see org.teiid.query.processor.xml.DocumentInProgress#isFinished()
- */
- public boolean isFinished() {
- return finished;
- }
-
- /**
- * @see org.teiid.query.processor.xml.DocumentInProgress#markAsFinished()
- */
- public void markAsFinished() throws TeiidComponentException{
- try {
- endDocument();
- } catch (SAXException e) {
- throw new TeiidComponentException(e);
- }
- finished = true;
- }
-
- private Element makeElement(NodeDescriptor descripter) {
- showState( "makeElement - TOP" ); //$NON-NLS-1$
- Element element = new Element(descripter, handler);
- element.setParent(currentParent);
- if (currentParent != null) {
- currentParent.addChild(element);
- }
- showState( "makeElement - BOT" ); //$NON-NLS-1$
- return element;
- }
-
- private void startDocument() throws SAXException{
- showState( "startDocument - TOP" ); //$NON-NLS-1$
- transformer.setOutputProperty(OutputKeys.ENCODING, documentEncoding);
- if(isFormatted){
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");//$NON-NLS-1$
- }
- handler.startDocument();
- showState( "startDocument - BOT" ); //$NON-NLS-1$
- }
-
- private void endDocument() throws SAXException{
- //special case: only one root element
- endElement(currentObject);
- handler.endDocument();
- }
-
- /**
- * @param content
- * @param textNormalizationMode
- * preserve No normalization is done, the value is not changed for element content
- * replace All occurrences of #x9 (tab), #xA (line feed) and #xD (carriage return) are replaced with #x20 (space)
- * collapse After the processing implied by replace, contiguous sequences of #x20's are collapsed to a single #x20, and leading and trailing #x20's are removed.
- *
- * @return
- * @since 4.3
-
- */
- public static String normalizeText(String content, String textNormalizationMode) {
- String result = content;
- String singleSpace = " "; //$NON-NLS-1$
- if(textNormalizationMode.equalsIgnoreCase(MappingNodeConstants.NORMALIZE_TEXT_REPLACE)) {
- result = result.replaceAll("\\s", singleSpace); //$NON-NLS-1$
- }else if(textNormalizationMode.equalsIgnoreCase(MappingNodeConstants.NORMALIZE_TEXT_COLLAPSE)){
- result = result.replaceAll("\\s+", singleSpace); //$NON-NLS-1$
- result = result.trim();
- }
- return result;
- }
-
-
- private void showState( String sOccasion ) {
-
- if (LogManager.isMessageToBeRecorded(org.teiid.logging.LogConstants.CTX_XML_PLAN, MessageLevel.TRACE)) {
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"\n [showState] State Vars at: " + sOccasion} ); //$NON-NLS-1$
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] currentParent: " + currentParent} ); //$NON-NLS-1$
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] currentObject: " + currentObject} ); //$NON-NLS-1$
-
- if ( currentObject != null ) {
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] currentObject.getNillableDescriptor(): " + currentObject.getNillableDescriptor()}); //$NON-NLS-1$
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] workingElements: " + currentObject.getChildren()}); //$NON-NLS-1$
- }
- if ( currentParent != null ) {
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] currentParent.getParent(): " + currentParent.getParent()}); //$NON-NLS-1$
- } else {
- LogManager.logTrace(org.teiid.logging.LogConstants.CTX_XML_PLAN, new Object[]{"[showState] currentParent.getParent(): is NULL "}); //$NON-NLS-1$
- }
- }
- }
-
- @Override
- public FileStore getFileStore() {
- return this.store;
- }
-
-}
Modified: trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLPlan.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLPlan.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLPlan.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -162,7 +162,7 @@
DocumentInProgress doc = env.getDocumentInProgress();
if (doc != null && doc.isFinished()) {
this.env.setDocumentInProgress(null);
- XMLType xml = new XMLType(XMLUtil.createSQLXML(doc.getFileStore()));
+ XMLType xml = new XMLType(doc.getSQLXML());
// check to see if we need to do any post validation on the document.
if (getContext().validateXML()){
Reader reader;
Modified: trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLUtil.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/processor/xml/XMLUtil.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -23,9 +23,12 @@
package org.teiid.query.processor.xml;
import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
import java.io.Writer;
import javax.xml.transform.TransformerException;
@@ -33,50 +36,77 @@
import org.teiid.common.buffer.BufferManager;
import org.teiid.common.buffer.FileStore;
import org.teiid.common.buffer.FileStore.FileStoreOutputStream;
-import org.teiid.common.buffer.impl.BufferManagerImpl;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
+import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.InputStreamFactory;
import org.teiid.core.types.SQLXMLImpl;
import org.teiid.core.types.Streamable;
import org.teiid.core.types.XMLTranslator;
-
-
/**
* Utility methods to be used with the XML and XQuery processing.
*/
public class XMLUtil {
- //horrible hack
- private static BufferManager bufferManager;
-
- public static void setBufferManager(BufferManager bufferManager) {
- XMLUtil.bufferManager = bufferManager;
+ public static final class FileStoreInputStreamFactory extends InputStreamFactory {
+ private final FileStore lobBuffer;
+ private final FileStoreOutputStream fsos;
+
+ public FileStoreInputStreamFactory(FileStore lobBuffer, String encoding) {
+ super(encoding);
+ this.lobBuffer = lobBuffer;
+ fsos = lobBuffer.createOutputStream(DataTypeManager.MAX_LOB_MEMORY_BYTES);
+ this.lobBuffer.setCleanupReference(this);
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ if (!fsos.bytesWritten()) {
+ return new ByteArrayInputStream(fsos.getBuffer(), 0, fsos.getCount());
+ }
+ //TODO: adjust the buffer size, and/or develop a shared buffer strategy
+ return new BufferedInputStream(lobBuffer.createInputStream(0));
+ }
+
+ @Override
+ public long getLength() {
+ return lobBuffer.getLength();
+ }
+
+ public Writer getWriter() {
+ try {
+ return new OutputStreamWriter(fsos, Streamable.ENCODING);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public OutputStream getOuptStream() {
+ return fsos;
+ }
+
+ @Override
+ public void free() throws IOException {
+ lobBuffer.remove();
+ }
}
-
- public static SQLXMLImpl saveToBufferManager(XMLTranslator translator) throws TeiidComponentException, TeiidProcessingException {
- return saveToBufferManager(bufferManager, translator, Streamable.STREAMING_BATCH_SIZE_IN_BYTES);
- }
-
+
/**
* 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, int maxMemorySize)
+ public static SQLXMLImpl saveToBufferManager(BufferManager bufferMgr, XMLTranslator translator)
throws TeiidComponentException, TeiidProcessingException {
boolean success = false;
final FileStore lobBuffer = bufferMgr.createFileStore("xml"); //$NON-NLS-1$
+ FileStoreInputStreamFactory fsisf = new FileStoreInputStreamFactory(lobBuffer, Streamable.ENCODING);
try{
- FileStoreOutputStream fsos = lobBuffer.createOutputStream(maxMemorySize);
- Writer writer = new OutputStreamWriter(fsos, Streamable.ENCODING);
+ Writer writer = fsisf.getWriter();
translator.translate(writer);
writer.close();
- if (!fsos.bytesWritten()) {
- return new SQLXMLImpl(fsos.toByteArray());
- }
success = true;
- return createSQLXML(lobBuffer);
+ return new SQLXMLImpl(fsisf);
} catch(IOException e) {
throw new TeiidComponentException(e);
} catch(TransformerException e) {
@@ -88,21 +118,4 @@
}
}
- public static SQLXMLImpl createSQLXML(final FileStore lobBuffer) {
- SQLXMLImpl sqlXML = new SQLXMLImpl(new InputStreamFactory(Streamable.ENCODING) {
- @Override
- public InputStream getInputStream() throws IOException {
- //TODO: adjust the buffer size, and/or develop a shared buffer strategy
- return new BufferedInputStream(lobBuffer.createInputStream(0));
- }
-
- @Override
- public void free() throws IOException {
- lobBuffer.remove();
- }
- });
- lobBuffer.setCleanupReference(sqlXML);
- return sqlXML;
- }
-
}
\ No newline at end of file
Modified: trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -135,4 +135,5 @@
public void visit(XMLSerialize obj) {}
public void visit(XMLQuery obj) {}
public void visit(QueryString obj) {}
+ public void visit(XMLParse obj) {}
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -99,6 +99,7 @@
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLForest;
import org.teiid.query.sql.symbol.XMLNamespaces;
+import org.teiid.query.sql.symbol.XMLParse;
import org.teiid.query.sql.symbol.XMLQuery;
import org.teiid.query.sql.symbol.XMLSerialize;
@@ -593,6 +594,13 @@
postVisitVisitor(obj);
}
+ @Override
+ public void visit(XMLParse obj) {
+ preVisitVisitor(obj);
+ visitNode(obj.getExpression());
+ postVisitVisitor(obj);
+ }
+
public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean order) {
PreOrPostOrderNavigator nav = new PreOrPostOrderNavigator(visitor, order);
object.acceptVisitor(nav);
Added: trunk/engine/src/main/java/org/teiid/query/sql/symbol/XMLParse.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/XMLParse.java (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/XMLParse.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -0,0 +1,108 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.sql.symbol;
+
+import org.teiid.core.types.DataTypeManager;
+import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.visitor.SQLStringVisitor;
+
+public class XMLParse implements Expression {
+
+ private static final long serialVersionUID = 1535624727897336538L;
+
+ private boolean document;
+ private Expression expression;
+ private boolean wellFormed;
+
+ @Override
+ public Class<?> getType() {
+ return DataTypeManager.DefaultDataClasses.XML;
+ }
+
+ public Expression getExpression() {
+ return expression;
+ }
+
+ public boolean isDocument() {
+ return document;
+ }
+
+ public void setDocument(boolean document) {
+ this.document = document;
+ }
+
+ public void setExpression(Expression expression) {
+ this.expression = expression;
+ }
+
+ public boolean isWellFormed() {
+ return wellFormed;
+ }
+
+ public void setWellFormed(boolean wellFormed) {
+ this.wellFormed = wellFormed;
+ }
+
+ @Override
+ public boolean isResolved() {
+ return expression.isResolved();
+ }
+
+ @Override
+ public void acceptVisitor(LanguageVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public XMLParse clone() {
+ XMLParse clone = new XMLParse();
+ clone.document = this.document;
+ clone.expression = (Expression)this.expression.clone();
+ clone.wellFormed = this.wellFormed;
+ return clone;
+ }
+
+ @Override
+ public int hashCode() {
+ return expression.hashCode();
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof XMLParse)) {
+ return false;
+ }
+ XMLParse other = (XMLParse)obj;
+ return document == other.document
+ && this.expression.equals(other.expression)
+ && this.wellFormed == other.wellFormed;
+ }
+
+ @Override
+ public String toString() {
+ return SQLStringVisitor.getSQLString(this);
+ }
+
+}
Property changes on: trunk/engine/src/main/java/org/teiid/query/sql/symbol/XMLParse.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -65,6 +65,7 @@
import org.teiid.query.sql.symbol.SearchedCaseExpression;
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.symbol.XMLElement;
+import org.teiid.query.sql.symbol.XMLParse;
import org.teiid.query.sql.symbol.XMLSerialize;
@@ -116,6 +117,11 @@
obj.setExpression(replaceExpression(obj.getExpression()));
}
+ @Override
+ public void visit(XMLParse obj) {
+ obj.setExpression(replaceExpression(obj.getExpression()));
+ }
+
private void replaceSymbols(List symbols, boolean alias) {
for (int i = 0; i < symbols.size(); i++) {
Object symbol = symbols.get(i);
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -24,6 +24,7 @@
import static org.teiid.language.SQLConstants.Reserved.*;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -32,6 +33,7 @@
import java.util.List;
import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.types.XMLType;
import org.teiid.core.util.StringUtil;
import org.teiid.language.SQLConstants;
import org.teiid.language.SQLConstants.NonReserved;
@@ -121,6 +123,7 @@
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLForest;
import org.teiid.query.sql.symbol.XMLNamespaces;
+import org.teiid.query.sql.symbol.XMLParse;
import org.teiid.query.sql.symbol.XMLQuery;
import org.teiid.query.sql.symbol.XMLSerialize;
import org.teiid.query.sql.symbol.XMLNamespaces.NamespaceItem;
@@ -1154,8 +1157,16 @@
} else if(type.equals(DataTypeManager.DefaultDataClasses.DATE)) {
constantParts = new Object[] { "{d'", obj.getValue().toString(), "'}" }; //$NON-NLS-1$ //$NON-NLS-2$
} else if(type.equals(DataTypeManager.DefaultDataClasses.XML)){
- constantParts = new Object[] { "{x '", escapeStringValue(obj.getValue().toString(), "'"), "'}" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- } else {
+ XMLType value = (XMLType)obj.getValue();
+ if (Boolean.TRUE.equals(value.isInMemory())) {
+ try {
+ constantParts = new Object[] { "{x '", escapeStringValue(value.getString(), "'"), "'}" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ } catch (SQLException e) {
+
+ }
+ }
+ }
+ if (constantParts == null) {
String strValue = obj.getValue().toString();
strValue = escapeStringValue(strValue, "'"); //$NON-NLS-1$
constantParts = new Object[] { "'", strValue, "'" }; //$NON-NLS-1$ //$NON-NLS-2$
@@ -1821,6 +1832,24 @@
}
parts.add(")"); //$NON-NLS-1$
}
+
+ @Override
+ public void visit(XMLParse obj) {
+ parts.add(XMLPARSE);
+ parts.add(Tokens.LPAREN);
+ if (obj.isDocument()) {
+ parts.add(NonReserved.DOCUMENT);
+ } else {
+ parts.add(NonReserved.CONTENT);
+ }
+ parts.add(SPACE);
+ parts.add(registerNode(obj.getExpression()));
+ if (obj.isWellFormed()) {
+ parts.add(SPACE);
+ parts.add(NonReserved.WELLFORMED);
+ }
+ parts.add(Tokens.RPAREN);
+ }
public static String escapeSinglePart(String part) {
if(isReservedWord(part)) {
Modified: trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/util/CommandContext.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -32,7 +32,6 @@
import org.teiid.api.exception.query.QueryProcessingException;
import org.teiid.common.buffer.BufferManager;
import org.teiid.core.TeiidComponentException;
-import org.teiid.core.types.Streamable;
import org.teiid.core.util.ArgCheck;
import org.teiid.query.QueryPlugin;
import org.teiid.query.eval.SecurityFunctionEvaluator;
@@ -79,8 +78,6 @@
/** Indicate whether statistics should be collected for relational node processing*/
private boolean collectNodeStatistics;
- private int streamingBatchSize = Streamable.STREAMING_BATCH_SIZE_IN_BYTES;
-
private Random random = null;
private SecurityFunctionEvaluator securityFunctionEvaluator;
@@ -274,19 +271,9 @@
return this.globalState.collectNodeStatistics;
}
- public int getStreamingBatchSize() {
- return globalState.streamingBatchSize;
- }
-
- public void setStreamingBatchSize(int streamingBatchSize) {
- this.globalState.streamingBatchSize = streamingBatchSize;
- }
-
-
public int getConnectorBatchSize() {
return this.globalState.connectorBatchSize;
}
-
public void setConnectorBatchSize(int connectorBatchSize) {
this.globalState.connectorBatchSize = connectorBatchSize;
Modified: trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -110,6 +110,7 @@
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLForest;
import org.teiid.query.sql.symbol.XMLNamespaces;
+import org.teiid.query.sql.symbol.XMLParse;
import org.teiid.query.sql.symbol.XMLQuery;
import org.teiid.query.sql.util.SymbolMap;
import org.teiid.query.sql.visitor.AggregateSymbolCollectorVisitor;
@@ -1315,5 +1316,14 @@
}
}
}
+
+ @Override
+ public void visit(XMLParse obj) {
+ if (obj.getExpression().getType() != DataTypeManager.DefaultDataClasses.STRING &&
+ obj.getExpression().getType() != DataTypeManager.DefaultDataClasses.CLOB &&
+ obj.getExpression().getType() != DataTypeManager.DefaultDataClasses.BLOB) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.xmlserialize_type"), obj); //$NON-NLS-1$
+ }
+ }
}
Modified: trunk/engine/src/main/java/org/teiid/query/xquery/saxon/SaxonXQueryExpression.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/xquery/saxon/SaxonXQueryExpression.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/java/org/teiid/query/xquery/saxon/SaxonXQueryExpression.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -70,6 +70,7 @@
import net.sf.saxon.value.SequenceType;
import org.teiid.api.exception.query.QueryResolverException;
+import org.teiid.common.buffer.BufferManager;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidRuntimeException;
@@ -389,7 +390,7 @@
}
}
- public XMLType createXMLType(final SequenceIterator iter, boolean emptyOnEmpty) throws XPathException, TeiidComponentException, TeiidProcessingException {
+ public XMLType createXMLType(final SequenceIterator iter, BufferManager bufferManager, boolean emptyOnEmpty) throws XPathException, TeiidComponentException, TeiidProcessingException {
Item item = iter.next();
if (item == null && !emptyOnEmpty) {
return null;
@@ -413,7 +414,7 @@
if (next != null) {
type = Type.CONTENT;
}
- SQLXMLImpl xml = XMLUtil.saveToBufferManager(new XMLTranslator() {
+ SQLXMLImpl xml = XMLUtil.saveToBufferManager(bufferManager, new XMLTranslator() {
@Override
public void translate(Writer writer) throws TransformerException,
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2010-06-15 16:49:28 UTC (rev 2233)
@@ -3317,7 +3317,11 @@
)*
]
<RPAREN>
- )
+ )
+ | expression = xmlParse(info)
+ {
+ return expression;
+ }
| expression = xmlElement(info)
{
return expression;
@@ -3385,6 +3389,31 @@
}
}
+XMLParse xmlParse(ParseInfo info) :
+{
+ Expression expr = null;
+ String doc = null;
+ boolean wellformed = false;
+}
+{
+ <XMLPARSE><LPAREN>
+ doc = nonReserved("DOCUMENT", "CONTENT")
+ expr = expression(info)
+ [nonReserved("WELLFORMED")
+ {
+ wellformed = true;
+ }
+ ]
+ <RPAREN>
+ {
+ XMLParse result = new XMLParse();
+ result.setDocument("document".equalsIgnoreCase(doc));
+ result.setExpression(expr);
+ result.setWellFormed(wellformed);
+ return result;
+ }
+}
+
QueryString queryString(ParseInfo info) :
{
Expression path = null;
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatement.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatement.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestPreparedStatement.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -244,7 +244,7 @@
ConnectorManagerRepository repo = Mockito.mock(ConnectorManagerRepository.class);
Mockito.stub(repo.getConnectorManager(Mockito.anyString())).toReturn(new AutoGenDataService());
- serverRequest.initialize(request, BufferManagerFactory.getStandaloneBufferManager(), null, new FakeTransactionService(), DEBUG, null, workContext, 101024,repo, false);
+ serverRequest.initialize(request, BufferManagerFactory.getStandaloneBufferManager(), null, new FakeTransactionService(), DEBUG, null, workContext, repo,false);
serverRequest.setMetadata(capFinder, metadata, null);
serverRequest.processRequest();
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestRequest.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestRequest.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestRequest.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -84,7 +84,7 @@
RequestMessage message = new RequestMessage();
DQPWorkContext workContext = FakeMetadataFactory.buildWorkContext(metadata, FakeMetadataFactory.example1VDB());
- request.initialize(message, null, null,new FakeTransactionService(),false, null, workContext, 101024, repo, false);
+ request.initialize(message, null, null,new FakeTransactionService(),false, null, workContext, repo, false);
request.initMetadata();
request.validateAccess(command);
}
@@ -139,7 +139,7 @@
request.initialize(message, Mockito.mock(BufferManager.class),
new FakeDataManager(), new FakeTransactionService(), false, null, workContext,
- 101024, repo, false);
+ repo, false);
request.processRequest();
return request;
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -114,6 +114,7 @@
import org.teiid.query.sql.symbol.XMLElement;
import org.teiid.query.sql.symbol.XMLForest;
import org.teiid.query.sql.symbol.XMLNamespaces;
+import org.teiid.query.sql.symbol.XMLParse;
import org.teiid.query.sql.symbol.XMLQuery;
import org.teiid.query.sql.symbol.XMLSerialize;
@@ -6824,5 +6825,13 @@
f.setPassing(Arrays.asList(new DerivedColumn(null, new ElementSymbol("foo"))));
helpTestExpression("xmlquery('/x' passing foo null on empty)", "XMLQUERY('/x' PASSING foo NULL ON EMPTY)", f);
}
+
+ @Test public void testXmlParse() throws Exception {
+ XMLParse f = new XMLParse();
+ f.setDocument(true);
+ f.setExpression(new ElementSymbol("x"));
+ f.setWellFormed(true);
+ helpTestExpression("xmlparse(document x wellformed)", "XMLPARSE(DOCUMENT x WELLFORMED)", f);
+ }
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestProcessor.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -135,13 +135,15 @@
}
static ProcessorPlan helpGetPlan(Command command, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) {
- CommandContext context = new CommandContext();
- context.setProcessorBatchSize(2000);
- context.setConnectorBatchSize(2000);
- return helpGetPlan(command, metadata, capFinder, context);
+ CommandContext context = createCommandContext();
+ try {
+ return helpGetPlan(command, metadata, capFinder, context);
+ } catch (TeiidException e) {
+ throw new RuntimeException(e);
+ }
}
- static ProcessorPlan helpGetPlan(Command command, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, CommandContext context) {
+ static ProcessorPlan helpGetPlan(Command command, QueryMetadataInterface metadata, CapabilitiesFinder capFinder, CommandContext context) throws TeiidException {
if(DEBUG) System.out.println("\n####################################\n" + command); //$NON-NLS-1$
AnalysisRecord analysisRecord = new AnalysisRecord(false, DEBUG);
try {
@@ -163,10 +165,6 @@
assertNotNull("Output elements of process plan are null", process.getOutputElements()); //$NON-NLS-1$
return process;
- } catch (TeiidComponentException e) {
- throw new RuntimeException(e);
- } catch (TeiidProcessingException e) {
- throw new RuntimeException(e);
} finally {
if(DEBUG) {
System.out.println(analysisRecord.getDebugLog());
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -24,11 +24,19 @@
import static org.teiid.query.processor.TestProcessor.*;
+import java.io.FileInputStream;
import java.util.Arrays;
import java.util.List;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.teiid.api.exception.query.ExpressionEvaluationException;
+import org.teiid.core.types.BlobImpl;
+import org.teiid.core.types.BlobType;
+import org.teiid.core.types.InputStreamFactory;
+import org.teiid.core.util.ObjectConverterUtil;
+import org.teiid.core.util.UnitTestUtil;
+import org.teiid.query.optimizer.capabilities.DefaultCapabilitiesFinder;
import org.teiid.query.unittest.FakeMetadataFactory;
@SuppressWarnings({"nls", "unchecked"})
@@ -267,6 +275,75 @@
process(sql, expected);
}
+ @Test public void testXmlParseDoc() throws Exception {
+ String sql = "select xmlparse(document '<a/>')"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ Arrays.asList("<a/>")
+ };
+
+ process(sql, expected);
+ }
+
+ @Test(expected=ExpressionEvaluationException.class) public void testXmlParseDocException() throws Exception {
+ String sql = "select xmlparse(document 'a<a/>')"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ };
+
+ process(sql, expected);
+ }
+
+ @Test public void testXmlParseContent() throws Exception {
+ String sql = "select xmlparse(content 'a<a/>')"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ Arrays.asList("a<a/>")
+ };
+
+ process(sql, expected);
+ }
+
+ @Test(expected=ExpressionEvaluationException.class) public void testXmlParseContentException() throws Exception {
+ String sql = "select xmlparse(content 'a<')"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ };
+
+ process(sql, expected);
+ }
+
+ //by pass the validation
+ @Test public void testXmlParseContentWellformed() throws Exception {
+ String sql = "select xmlparse(content 'a<' WELLFORMED)"; //$NON-NLS-1$
+
+ List<?>[] expected = new List<?>[] {
+ Arrays.asList("a<")
+ };
+
+ process(sql, expected);
+ }
+
+ @Test public void testXmlParseClob() throws Exception {
+ String sql = "select xmlparse(document cast(? as clob)) x"; //$NON-NLS-1$
+
+ List[] expected = new List[] {
+ Arrays.asList(ObjectConverterUtil.convertToString(new FileInputStream(UnitTestUtil.getTestDataFile("udf.xmi")))),
+ };
+
+ processPreparedStatement(sql, expected, dataManager, new DefaultCapabilitiesFinder(), FakeMetadataFactory.example1Cached(), Arrays.asList(TestTextTable.clobFromFile("udf.xmi")));
+ }
+
+ @Test public void testXmlParseBlob() throws Exception {
+ String sql = "select xmlparse(document cast(? as blob)) x"; //$NON-NLS-1$
+
+ List[] expected = new List[] {
+ Arrays.asList(ObjectConverterUtil.convertToString(new FileInputStream(UnitTestUtil.getTestDataFile("udf.xmi")))),
+ };
+
+ processPreparedStatement(sql, expected, dataManager, new DefaultCapabilitiesFinder(), FakeMetadataFactory.example1Cached(), Arrays.asList(blobFromFile("udf.xmi")));
+ }
+
private static FakeDataManager dataManager = new FakeDataManager();
@BeforeClass public static void oneTimeSetUp() {
@@ -274,9 +351,13 @@
}
private void process(String sql, List<?>[] expected) throws Exception {
- ProcessorPlan plan = helpGetPlan(helpParse(sql), FakeMetadataFactory.example1Cached());
+ ProcessorPlan plan = helpGetPlan(helpParse(sql), FakeMetadataFactory.example1Cached(), new DefaultCapabilitiesFinder(), createCommandContext());
helpProcess(plan, createCommandContext(), dataManager, expected);
}
+
+ public static BlobType blobFromFile(final String file) {
+ return new BlobType(new BlobImpl(new InputStreamFactory.FileInputStreamFactory(UnitTestUtil.getTestDataFile(file))));
+ }
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestTextTable.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestTextTable.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestTextTable.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -183,7 +183,7 @@
helpProcess(plan, createCommandContext(), dataManager, expectedResults);
}
- public ClobType clobFromFile(final String file) {
+ public static ClobType clobFromFile(final String file) {
return new ClobType(new ClobImpl(new InputStreamFactory.FileInputStreamFactory(UnitTestUtil.getTestDataFile(file)), -1));
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/xml/TestAddNodeInstruction.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/xml/TestAddNodeInstruction.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/test/java/org/teiid/query/processor/xml/TestAddNodeInstruction.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -24,24 +24,18 @@
import java.util.Properties;
+import junit.framework.TestCase;
+
import org.teiid.common.buffer.BufferManagerFactory;
import org.teiid.common.buffer.FileStore;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.types.Streamable;
import org.teiid.core.util.ObjectConverterUtil;
import org.teiid.query.mapping.xml.MappingNodeConstants;
-import org.teiid.query.processor.xml.AddNodeInstruction;
-import org.teiid.query.processor.xml.DocumentInProgress;
-import org.teiid.query.processor.xml.NodeDescriptor;
-import org.teiid.query.processor.xml.ProcessorInstruction;
-import org.teiid.query.processor.xml.Program;
-import org.teiid.query.processor.xml.SAXDocumentInProgress;
-import org.teiid.query.processor.xml.XMLContext;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.util.VariableContext;
-import junit.framework.TestCase;
-
/**
* Unit tests {@link AddNodeInstruction} class
*/
@@ -417,7 +411,7 @@
env.pushProgram(program);
FileStore fs = BufferManagerFactory.getStandaloneBufferManager().createFileStore("test"); //$NON-NLS-1$
- DocumentInProgress doc = new SAXDocumentInProgress(fs);
+ DocumentInProgress doc = new DocumentInProgress(fs, Streamable.ENCODING);
env.setDocumentInProgress(doc);
//add fake root, move to child
@@ -431,7 +425,7 @@
doc.moveToParent();
doc.markAsFinished();
- String actualDoc = new String(ObjectConverterUtil.convertToByteArray(fs.createInputStream(0)));
+ String actualDoc = ObjectConverterUtil.convertToString(doc.getSQLXML().getCharacterStream());
return actualDoc;
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/xml/TestSAXDocumentInProgress.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/xml/TestSAXDocumentInProgress.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/test/java/org/teiid/query/processor/xml/TestSAXDocumentInProgress.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -24,9 +24,10 @@
import org.teiid.common.buffer.BufferManagerFactory;
import org.teiid.common.buffer.FileStore;
+import org.teiid.core.types.Streamable;
import org.teiid.query.mapping.xml.MappingNodeConstants;
import org.teiid.query.processor.xml.NodeDescriptor;
-import org.teiid.query.processor.xml.SAXDocumentInProgress;
+import org.teiid.query.processor.xml.DocumentInProgress;
import junit.framework.TestCase;
@@ -40,7 +41,7 @@
public void testLargeDocument()throws Exception{
FileStore fs = BufferManagerFactory.getStandaloneBufferManager().createFileStore("test"); //$NON-NLS-1$
- SAXDocumentInProgress doc = new SAXDocumentInProgress(fs);
+ DocumentInProgress doc = new DocumentInProgress(fs, Streamable.ENCODING);
//long startTime = System.currentTimeMillis();
doc.setDocumentFormat(true);
NodeDescriptor descriptor = NodeDescriptor.createNodeDescriptor("Root", null, true, null, null, null,false, null, MappingNodeConstants.NORMALIZE_TEXT_PRESERVE);//$NON-NLS-1$
@@ -63,14 +64,14 @@
}
public void testNormalizationPreserve() throws Exception{
- assertEquals(SAXDocumentInProgress.normalizeText(originalText,MappingNodeConstants.NORMALIZE_TEXT_PRESERVE), originalText);
+ assertEquals(DocumentInProgress.normalizeText(originalText,MappingNodeConstants.NORMALIZE_TEXT_PRESERVE), originalText);
}
public void testNormalizationReplace() throws Exception{
String expectedResult = " Hello my tests for preserve, replace, collapse. "; //$NON-NLS-1$
- assertEquals(SAXDocumentInProgress.normalizeText(originalText,MappingNodeConstants.NORMALIZE_TEXT_REPLACE), expectedResult);
+ assertEquals(DocumentInProgress.normalizeText(originalText,MappingNodeConstants.NORMALIZE_TEXT_REPLACE), expectedResult);
}
public void testNormalizationCollapse() throws Exception{
String expectedResult = "Hello my tests for preserve, replace, collapse."; //$NON-NLS-1$
- assertEquals(SAXDocumentInProgress.normalizeText(originalText,MappingNodeConstants.NORMALIZE_TEXT_COLLAPSE), expectedResult);
+ assertEquals(DocumentInProgress.normalizeText(originalText,MappingNodeConstants.NORMALIZE_TEXT_COLLAPSE), expectedResult);
}
}
Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -2268,7 +2268,7 @@
}
@Test public void testRewriteXmlElement() throws Exception {
- String original = "convert(xmlelement(name a, xmlattributes('b' as c)), string)"; //$NON-NLS-1$
+ String original = "xmlserialize(document xmlelement(name a, xmlattributes('b' as c)) as string)"; //$NON-NLS-1$
QueryMetadataInterface metadata = FakeMetadataFactory.exampleBQTCached();
helpTestRewriteExpression(original, "'<a c=\"b\"></a>'", metadata);
}
Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2010-06-15 16:25:38 UTC (rev 2232)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2010-06-15 16:49:28 UTC (rev 2233)
@@ -2031,4 +2031,7 @@
helpValidate("select xmlelement(\":\")", new String[] {"XMLELEMENT(NAME \":\")"}, FakeMetadataFactory.example1Cached());
}
+ @Test public void testXmlParse() throws Exception {
+ helpValidate("select xmlparse(content e2) from pm1.g1", new String[] {"XMLPARSE(CONTENT e2)"}, FakeMetadataFactory.example1Cached());
+ }
}
More information about the teiid-commits
mailing list