Author: shawkins
Date: 2010-05-03 13:13:39 -0400 (Mon, 03 May 2010)
New Revision: 2092
Removed:
trunk/engine/src/main/java/com/metamatrix/query/processor/xml/XMLPostProcessor.java
Modified:
trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java
trunk/common-core/src/main/java/com/metamatrix/common/types/basic/ClobToSQLXMLTransform.java
trunk/common-core/src/test/java/com/metamatrix/common/types/basic/TestStringToXmlTransform.java
trunk/connector-api/src/main/java/org/teiid/connector/api/SourceSystemFunctions.java
trunk/connector-api/src/main/java/org/teiid/connector/language/SQLReservedWords.java
trunk/documentation/reference/src/main/docbook/en-US/content/federated_planning.xml
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml
trunk/documentation/reference/src/main/docbook/en-US/images/query_plan.png
trunk/engine/src/main/java/com/metamatrix/query/eval/SecurityFunctionEvaluator.java
trunk/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java
trunk/engine/src/main/java/com/metamatrix/query/function/source/SecuritySystemFunctions.java
trunk/engine/src/main/java/com/metamatrix/query/function/source/SystemSource.java
trunk/engine/src/main/java/com/metamatrix/query/function/source/XMLSystemFunctions.java
trunk/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitor.java
trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/java/com/metamatrix/query/util/CommandContext.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
trunk/engine/src/main/resources/com/metamatrix/query/i18n.properties
trunk/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java
trunk/engine/src/test/java/com/metamatrix/query/processor/xml/TestXMLProcessor.java
Log:
TEIID-1020 promoting stylesheet application to a system function, rather than a statement
property. also correcting the reference and adding a hasrole call with only a single
parameter
Modified: trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java 2010-05-03
17:07:09 UTC (rev 2091)
+++ trunk/client/src/main/java/org/teiid/jdbc/DatabaseMetaDataImpl.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -72,7 +72,7 @@
final static String KEY_WORDS = "OPTION, BIGDECIMAL"+ //$NON-NLS-1$
", BIGDECIMAL, BIGINTEGER, BREAK, BYTE, CRITERIA, ERROR, FN, LIMIT, LONG, LOOP,
MAKEDEP, MAKENOTDEP"+ //$NON-NLS-1$
", NOCACHE, OJ, SQL_TSI_FRAC_SECOND, SQL_TSI_SECOND, SQL_TSI_MINUTE, SQL_TSI_HOUR,
SQL_TSI_DAY, SQL_TSI_WEEK, SQL_TSI_MONTH"+ //$NON-NLS-1$
- ", SQL_TSI_QUARTER, SQL_TSI_YEAR, STRING, VIRTUAL, WHILE"; //$NON-NLS-1$
+ ", SQL_TSI_QUARTER, SQL_TSI_YEAR, STRING, TIMESTAMPADD, TIMESTAMPDIFF, VIRTUAL,
WHILE"; //$NON-NLS-1$
// constant value giving preferred name for a procedure
private final static String PROCEDURE_TERM = "StoredProcedure";
//$NON-NLS-1$
// constant value giving the names of numeric functions supported
Modified: trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java
===================================================================
--- trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java 2010-05-03 17:07:09 UTC
(rev 2091)
+++ trunk/client/src/main/java/org/teiid/jdbc/TeiidStatement.java 2010-05-03 17:13:39 UTC
(rev 2092)
@@ -22,8 +22,6 @@
package org.teiid.jdbc;
-import java.io.IOException;
-import java.io.Reader;
import java.io.Serializable;
import java.util.Collection;
@@ -80,21 +78,6 @@
Collection<Annotation> getAnnotations();
/**
- * Attach a stylesheet to be applied on the server for XML queries
- * executed with this Statement.
- * @param reader Reader for reading a stylesheet in XML
- * @throws IOException If an error occurs reading the stylesheet
- * @deprecated
- */
- void attachStylesheet(Reader reader) throws IOException;
-
- /**
- * Clear any previously attached stylesheet for this Statement object.
- * @deprecated
- */
- void clearStylesheet();
-
- /**
* Get ID for last execution which can be used for matching up executions
* on the client side with executions in the server logs.
* @return String identifier for the last execution
Modified:
trunk/common-core/src/main/java/com/metamatrix/common/types/basic/ClobToSQLXMLTransform.java
===================================================================
---
trunk/common-core/src/main/java/com/metamatrix/common/types/basic/ClobToSQLXMLTransform.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/common-core/src/main/java/com/metamatrix/common/types/basic/ClobToSQLXMLTransform.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -24,6 +24,7 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.Reader;
import java.nio.charset.Charset;
import java.sql.SQLException;
@@ -62,8 +63,10 @@
public Object transformDirect(Object value) throws TransformationException {
final ClobType source = (ClobType)value;
+ Reader reader = null;
try {
- StringToSQLXMLTransform.isXml(source.getCharacterStream());
+ reader = source.getCharacterStream();
+ StringToSQLXMLTransform.isXml(reader);
if (source.getReference() instanceof ClobImpl) {
ClobImpl clob = (ClobImpl)source.getReference();
return new XMLType(new SQLXMLImpl(clob.getStreamFactory()));
@@ -80,7 +83,14 @@
}));
} 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) {
+ }
+ }
+ }
}
/**
Modified:
trunk/common-core/src/test/java/com/metamatrix/common/types/basic/TestStringToXmlTransform.java
===================================================================
---
trunk/common-core/src/test/java/com/metamatrix/common/types/basic/TestStringToXmlTransform.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/common-core/src/test/java/com/metamatrix/common/types/basic/TestStringToXmlTransform.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -23,21 +23,19 @@
package com.metamatrix.common.types.basic;
//## JDBC4.0-begin ##
+import static org.junit.Assert.*;
+
import java.sql.SQLXML;
-//## JDBC4.0-end ##
-/*## JDBC3.0-JDK1.5-begin ##
-import com.metamatrix.core.jdbc.SQLXML;
-## JDBC3.0-JDK1.5-end ##*/
+import org.junit.Ignore;
+import org.junit.Test;
import com.metamatrix.common.types.TransformationException;
-import junit.framework.TestCase;
+@SuppressWarnings("nls")
+public class TestStringToXmlTransform {
-
-public class TestStringToXmlTransform extends TestCase {
-
- public void testGoodXML() throws Exception {
+ @Test public void testGoodXML() throws Exception {
String xml = "<?xml version=\"1.0\"
encoding=\"UTF-8\"?><customer>\n" + //$NON-NLS-1$
"<name>ABC</name>" + //$NON-NLS-1$
"<age>32</age>" + //$NON-NLS-1$
@@ -49,7 +47,7 @@
assertEquals(xml.replaceAll("[\r]", ""),
xmlValue.getString().replaceAll("[\r]", ""));
}
- public void testBadXML() {
+ @Test(expected=TransformationException.class) public void testBadXML() throws
Exception {
String xml = "<?xml version=\"1.0\"
encoding=\"UTF-8\"?><customer>\n" + //$NON-NLS-1$
"<name>ABC</name>" + //$NON-NLS-1$
"<age>32</age>" + //$NON-NLS-1$
@@ -57,10 +55,17 @@
StringToSQLXMLTransform transform = new StringToSQLXMLTransform();
- try {
- transform.transformDirect(xml);
- fail("exception expected"); //$NON-NLS-1$
- } catch (TransformationException e) {
- }
+ transform.transformDirect(xml);
}
+
+ @Ignore("TODO: allow for fragments in the xml type")
+ @Test public void testXMLFragment() throws Exception {
+ String xml = "<name>ABC</name>" + //$NON-NLS-1$
+ "<age>32</age>"; //$NON-NLS-1$
+
+ StringToSQLXMLTransform transform = new StringToSQLXMLTransform();
+
+ transform.transformDirect(xml);
+ }
+
}
Modified:
trunk/connector-api/src/main/java/org/teiid/connector/api/SourceSystemFunctions.java
===================================================================
---
trunk/connector-api/src/main/java/org/teiid/connector/api/SourceSystemFunctions.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/connector-api/src/main/java/org/teiid/connector/api/SourceSystemFunctions.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -136,5 +136,6 @@
//xml
public static final String XPATHVALUE = "xpathvalue"; //$NON-NLS-1$
+ public static final String XSLTRANSFORM = "xsltransform"; //$NON-NLS-1$
}
Modified:
trunk/connector-api/src/main/java/org/teiid/connector/language/SQLReservedWords.java
===================================================================
---
trunk/connector-api/src/main/java/org/teiid/connector/language/SQLReservedWords.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/connector-api/src/main/java/org/teiid/connector/language/SQLReservedWords.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -72,6 +72,8 @@
public static final String SQL_TSI_QUARTER = "SQL_TSI_QUARTER";
//$NON-NLS-1$
public static final String SQL_TSI_YEAR = "SQL_TSI_YEAR"; //$NON-NLS-1$
public static final String STRING = "STRING"; //$NON-NLS-1$
+ public static final String TIMESTAMPADD = "TIMESTAMPADD"; //$NON-NLS-1$
+ public static final String TIMESTAMPDIFF = "TIMESTAMPDIFF"; //$NON-NLS-1$
public static final String VIRTUAL = "VIRTUAL"; //$NON-NLS-1$
public static final String WHILE = "WHILE"; //$NON-NLS-1$
@@ -260,8 +262,6 @@
public static final String THEN = "THEN"; //$NON-NLS-1$
public static final String TIME = "TIME"; //$NON-NLS-1$
public static final String TIMESTAMP = "TIMESTAMP"; //$NON-NLS-1$
- public static final String TIMESTAMPADD = "TIMESTAMPADD"; //$NON-NLS-1$
- public static final String TIMESTAMPDIFF = "TIMESTAMPDIFF"; //$NON-NLS-1$
public static final String TIMEZONE_HOUR = "TIMEZONE_HOUR"; //$NON-NLS-1$
public static final String TIMEZONE_MINUTE = "TIMEZONE_MINUTE";
//$NON-NLS-1$
public static final String TO = "TO"; //$NON-NLS-1$
Modified:
trunk/documentation/reference/src/main/docbook/en-US/content/federated_planning.xml
===================================================================
---
trunk/documentation/reference/src/main/docbook/en-US/content/federated_planning.xml 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/documentation/reference/src/main/docbook/en-US/content/federated_planning.xml 2010-05-03
17:13:39 UTC (rev 2092)
@@ -396,7 +396,7 @@
<programlisting>
statement.execute("set showplan on");
ResultSet rs = statement.executeQuery("select ...");
-TeiidStatement tstatement = statement.unWrap(TeiidStatement.class);
+TeiidStatement tstatement = statement.unwrap(TeiidStatement.class);
PlanNode queryPlan = tstatement.getPlanDescription();
System.out.println(queryPlan);</programlisting>
</example>
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-05-03
17:07:09 UTC (rev 2091)
+++
trunk/documentation/reference/src/main/docbook/en-US/content/scalar_functions.xml 2010-05-03
17:13:39 UTC (rev 2092)
@@ -1944,6 +1944,19 @@
</para>
</entry>
</row>
+ <row>
+ <entry>
+ <para><code>XSLTRANSFORM(doc, xsl)</code></para>
+ </entry>
+ <entry>
+ <para>Takes a document and an xsl stylesheet and returns a
+ clob of the result.</para>
+ </entry>
+ <entry>
+ <para>Doc, xsl in {xml}. Return value is a clob.
+ </para>
+ </entry>
+ </row>
</tbody>
</tgroup>
</informaltable>
@@ -1970,16 +1983,29 @@
<tbody>
<row>
<entry>
+ <para><code>hasRole(roleName)</code>
+ </para>
+ </entry>
+ <entry>
+ <para>Whether the current caller has the role
+ roleName.</para>
+ </entry>
+ <entry>
+ <para>roleName must be a string, the return
+ type is Boolean.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
<para><code>hasRole(roleType, roleName)</code>
</para>
</entry>
<entry>
<para>Whether the current caller has the role
- roleName of roleType.</para>
+ roleName of roleType. See the 1 argument version above.</para>
</entry>
<entry>
- <para>roleType must be one of ('data','admin' ,
- 'repository') and roleName must be a string, the return
+ <para>roleType must be 'data' and roleName must be a string,
the return
type is Boolean.</para>
</entry>
</row>
Modified: trunk/documentation/reference/src/main/docbook/en-US/images/query_plan.png
===================================================================
(Binary files differ)
Modified:
trunk/engine/src/main/java/com/metamatrix/query/eval/SecurityFunctionEvaluator.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/eval/SecurityFunctionEvaluator.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/engine/src/main/java/com/metamatrix/query/eval/SecurityFunctionEvaluator.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -26,7 +26,6 @@
public interface SecurityFunctionEvaluator {
- public static final String ADMIN_ROLE = "admin"; //$NON-NLS-1$
public static final String DATA_ROLE = "data"; //$NON-NLS-1$
boolean hasRole(String roleType, String roleName) throws
MetaMatrixComponentException;
Modified: trunk/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/engine/src/main/java/com/metamatrix/query/function/FunctionLibrary.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -57,9 +57,6 @@
// Special environment variable lookup function
public static final String ENV = "env"; //$NON-NLS-1$
- // Special xpathvalue function
- public static final String XPATHVALUE = "xpathvalue"; //$NON-NLS-1$
-
// Special pseudo-functions only for XML queries
public static final String CONTEXT = "context"; //$NON-NLS-1$
public static final String ROWLIMIT = "rowlimit"; //$NON-NLS-1$
Modified:
trunk/engine/src/main/java/com/metamatrix/query/function/source/SecuritySystemFunctions.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/function/source/SecuritySystemFunctions.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/engine/src/main/java/com/metamatrix/query/function/source/SecuritySystemFunctions.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -30,6 +30,20 @@
public class SecuritySystemFunctions {
+ public static boolean hasRole(CommandContext context, Object roleName) throws
FunctionExecutionException {
+ SecurityFunctionEvaluator eval = context.getSecurityFunctionEvaluator();
+
+ if (eval == null) {
+ return true;
+ }
+
+ try {
+ return eval.hasRole(SecurityFunctionEvaluator.DATA_ROLE, (String)roleName);
+ } catch (MetaMatrixComponentException err) {
+ throw new FunctionExecutionException(err, err.getMessage());
+ }
+ }
+
public static boolean hasRole(CommandContext context, Object roleType, Object
roleName) throws FunctionExecutionException {
SecurityFunctionEvaluator eval = context.getSecurityFunctionEvaluator();
Modified:
trunk/engine/src/main/java/com/metamatrix/query/function/source/SystemSource.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/function/source/SystemSource.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/engine/src/main/java/com/metamatrix/query/function/source/SystemSource.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -167,6 +167,7 @@
// xml functions
addXpathFunction();
+ addXslTransformFunction();
addSecurityFunctions();
@@ -184,6 +185,11 @@
new FunctionParameter("roleType",
DataTypeManager.DefaultDataTypes.STRING,
QueryPlugin.Util.getString("SystemSource.hasRole_param1")), //$NON-NLS-1$
//$NON-NLS-2$
new FunctionParameter("roleName",
DataTypeManager.DefaultDataTypes.STRING,
QueryPlugin.Util.getString("SystemSource.hasRole_param2"))}, //$NON-NLS-1$
//$NON-NLS-2$
new FunctionParameter("result",
DataTypeManager.DefaultDataTypes.BOOLEAN,
QueryPlugin.Util.getString("SystemSource.hasRole_result")), false,
FunctionMethod.SESSION_DETERMINISTIC ) ); //$NON-NLS-1$ //$NON-NLS-2$
+
+ functions.add(new FunctionMethod("hasRole",
QueryPlugin.Util.getString("SystemSource.hasRole_description"), SECURITY,
FunctionMethod.CANNOT_PUSHDOWN, SECURITY_FUNCTION_CLASS, "hasRole",
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ new FunctionParameter[] {
+ new FunctionParameter("roleName",
DataTypeManager.DefaultDataTypes.STRING,
QueryPlugin.Util.getString("SystemSource.hasRole_param2"))}, //$NON-NLS-1$
//$NON-NLS-2$
+ new FunctionParameter("result",
DataTypeManager.DefaultDataTypes.BOOLEAN,
QueryPlugin.Util.getString("SystemSource.hasRole_result")), false,
FunctionMethod.SESSION_DETERMINISTIC ) ); //$NON-NLS-1$ //$NON-NLS-2$
}
private void addFormatNumberFunctions() {
@@ -890,6 +896,14 @@
}
+ private void addXslTransformFunction() {
+ functions.add(new FunctionMethod(SourceSystemFunctions.XSLTRANSFORM,
QueryPlugin.Util.getString("SystemSource.xsltransform_description"), XML,
XML_FUNCTION_CLASS, "xslTransform", //$NON-NLS-1$ //$NON-NLS-2$
+ new FunctionParameter[] {
+ new FunctionParameter("document",
DataTypeManager.DefaultDataTypes.XML,
QueryPlugin.Util.getString("SystemSource.xsltransform_param1")), //$NON-NLS-1$
//$NON-NLS-2$
+ new FunctionParameter("xsl",
DataTypeManager.DefaultDataTypes.XML,
QueryPlugin.Util.getString("SystemSource.xsltransform_param2"))}, //$NON-NLS-1$
//$NON-NLS-2$
+ new FunctionParameter("result",
DataTypeManager.DefaultDataTypes.CLOB,
QueryPlugin.Util.getString("SystemSource.xsltransform_result")) ) );
//$NON-NLS-1$ //$NON-NLS-2$
+ }
+
private void addTimeZoneFunctions() {
functions.add(new FunctionMethod(SourceSystemFunctions.MODIFYTIMEZONE,
QueryPlugin.Util.getString("SystemSource.modifyTimeZone_description"), DATETIME,
FUNCTION_CLASS, "modifyTimeZone", //$NON-NLS-1$ //$NON-NLS-2$
new FunctionParameter[] {
Modified:
trunk/engine/src/main/java/com/metamatrix/query/function/source/XMLSystemFunctions.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/function/source/XMLSystemFunctions.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/engine/src/main/java/com/metamatrix/query/function/source/XMLSystemFunctions.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -25,14 +25,29 @@
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
+import java.io.Writer;
import java.sql.SQLException;
import java.sql.SQLXML;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
import net.sf.saxon.trans.XPathException;
import com.metamatrix.api.exception.query.FunctionExecutionException;
+import com.metamatrix.common.types.ClobType;
+import com.metamatrix.common.types.DataTypeManager;
+import com.metamatrix.common.types.Streamable;
+import com.metamatrix.common.types.XMLTranslator;
+import com.metamatrix.common.types.XMLType;
import com.metamatrix.internal.core.xml.XPathHelper;
import com.metamatrix.query.QueryPlugin;
+import com.metamatrix.query.processor.xml.XMLUtil;
+import com.metamatrix.query.util.CommandContext;
@@ -72,4 +87,34 @@
}
}
+ @SuppressWarnings("unchecked")
+ public static ClobType xslTransform(CommandContext context, XMLType xmlResults, XMLType
styleSheet) throws Exception {
+ Reader styleSheetReader = styleSheet.getCharacterStream();
+ final Source styleSource = new StreamSource(styleSheetReader);
+ Reader reader = xmlResults.getCharacterStream();
+ final Source xmlSource = new StreamSource(reader);
+ try {
+ SQLXML result = XMLUtil.saveToBufferManager(context.getBufferManager(), new
XMLTranslator() {
+
+ @Override
+ public void translate(Writer writer) throws TransformerException {
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer = factory.newTransformer(styleSource);
+ // Feed the resultant I/O stream into the XSLT processor
+ transformer.transform(xmlSource, new StreamResult(writer));
+ }
+ }, Streamable.STREAMING_BATCH_SIZE_IN_BYTES);
+ return DataTypeManager.transformValue(new XMLType(result),
DataTypeManager.DefaultDataClasses.CLOB);
+ } finally {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ }
+ try {
+ styleSheetReader.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
}
Deleted:
trunk/engine/src/main/java/com/metamatrix/query/processor/xml/XMLPostProcessor.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/processor/xml/XMLPostProcessor.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/engine/src/main/java/com/metamatrix/query/processor/xml/XMLPostProcessor.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -1,199 +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 com.metamatrix.query.processor.xml;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.Writer;
-import java.sql.SQLException;
-import java.sql.SQLXML;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-
-import com.metamatrix.api.exception.MetaMatrixComponentException;
-import com.metamatrix.api.exception.MetaMatrixProcessingException;
-import com.metamatrix.common.buffer.BlockedException;
-import com.metamatrix.common.buffer.BufferManager;
-import com.metamatrix.common.buffer.TupleBatch;
-import com.metamatrix.common.types.Streamable;
-import com.metamatrix.common.types.XMLTranslator;
-import com.metamatrix.common.types.XMLType;
-import com.metamatrix.query.processor.ProcessorDataManager;
-import com.metamatrix.query.processor.ProcessorPlan;
-import com.metamatrix.query.util.CommandContext;
-import com.metamatrix.query.util.XMLFormatConstants;
-
-/**
- * TODO: sometime later this functionality should be handled with system functions
- */
-public class XMLPostProcessor extends ProcessorPlan {
-
- // Post-processing
- private String styleSheet;
- private String xmlFormat;
- private BufferManager bufferMgr;
- private ProcessorPlan plan;
-
- public XMLPostProcessor(ProcessorPlan plan) {
- this.plan = plan;
- }
-
- XMLType postProcessDocument(XMLType xmlDoc) throws MetaMatrixComponentException {
- try {
- return transformXML(xmlDoc);
- } catch (SQLException e) {
- throw new MetaMatrixComponentException(e);
- }
- }
-
- /**
- * <p> This method is used to transform the XML results obtained, by applying
transformations
- * using any style sheets that are added to the <code>Query</code> object.
- * @param xmlResults The xml result string that is being transformed using stylesheets
- * @return The xml string transformed using style sheets.
- * @throws MetaMatrixComponentException if there is an error trying to perform
transformation
- */
- private XMLType transformXML(XMLType xmlResults) throws SQLException,
MetaMatrixComponentException {
- final Source styleSource;
- if (styleSheet != null) {
- Reader styleReader = new StringReader(styleSheet);
- styleSource = new StreamSource(styleReader);
- } else {
- styleSource = null;
- }
-
- // get a reader object for the xml results
- //Reader xmlReader = new StringReader(xmlResults);
- // construct a Xlan source object for the xml results
- Reader reader = xmlResults.getCharacterStream();
- final Source xmlSource = new StreamSource(reader);
- try {
- // Convert the output target for use in Xalan-J 2
- SQLXML result = XMLUtil.saveToBufferManager(bufferMgr, new XMLTranslator() {
-
- @Override
- public void translate(Writer writer) throws TransformerException {
- TransformerFactory factory = TransformerFactory.newInstance();
- Transformer transformer = null;
- if (styleSource == null) {
- transformer = factory.newTransformer();
- } else {
- transformer = factory.newTransformer(styleSource);
- }
- if (XMLFormatConstants.XML_TREE_FORMAT.equals(xmlFormat)) {
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//$NON-NLS-1$
- }
- // Feed the resultant I/O stream into the XSLT processor
- transformer.transform(xmlSource, new StreamResult(writer));
- }
- }, Streamable.STREAMING_BATCH_SIZE_IN_BYTES);
- // obtain the stringified XML results for the
- return new XMLType(result);
- } finally {
- try {
- reader.close();
- } catch (IOException e) {
- }
- }
- }
-
- /**
- * <p> This method sets a style sheet to this object. The style sheet is
- * used to perform transformations on XML results
- * @param styleSheet A string representing a xslt styleSheet
- */
- public void setStylesheet(String styleSheet) {
- this.styleSheet = styleSheet;
- }
-
- /**
- * This method sets whether the documents should be returned in compact
- * format (no extraneous whitespace). Non-compact format is more human-readable
- * (and bigger). Additional formats may be possible in future.
- * @param xmlFormat A string giving the format in which xml results need to be
returned
- */
- public void setXMLFormat(String xmlFormat) {
- this.xmlFormat = xmlFormat;
- }
-
- @Override
- public ProcessorPlan clone() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void close() throws MetaMatrixComponentException {
- this.plan.close();
- }
-
- @Override
- public List getOutputElements() {
- return this.plan.getOutputElements();
- }
-
- @Override
- public void initialize(CommandContext context,
- ProcessorDataManager dataMgr, BufferManager bufferMgr) {
- this.bufferMgr = bufferMgr;
- }
-
- @Override
- public TupleBatch nextBatch() throws BlockedException,
- MetaMatrixComponentException, MetaMatrixProcessingException {
- TupleBatch batch = plan.nextBatch();
- List<List<XMLType>> result = new
ArrayList<List<XMLType>>(batch.getAllTuples().length);
- for (List tuple : batch.getAllTuples()) {
- result.add(Arrays.asList(postProcessDocument((XMLType)tuple.get(0))));
- }
- TupleBatch resultBatch = new TupleBatch(batch.getBeginRow(), result);
- resultBatch.setTerminationFlag(batch.getTerminationFlag());
- return resultBatch;
- }
-
- @Override
- public void open() throws MetaMatrixComponentException,
- MetaMatrixProcessingException {
- this.plan.open();
- }
-
- @Override
- public boolean requiresTransaction(boolean transactionalReads) {
- return plan.requiresTransaction(transactionalReads);
- }
-
- @Override
- public void reset() {
- this.plan.reset();
- }
-
-}
\ No newline at end of file
Modified:
trunk/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitor.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitor.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/engine/src/main/java/com/metamatrix/query/resolver/util/ResolverVisitor.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -31,6 +31,8 @@
import java.util.List;
import java.util.Map;
+import org.teiid.connector.api.SourceSystemFunctions;
+
import net.sf.saxon.trans.XPathException;
import com.metamatrix.api.exception.MetaMatrixComponentException;
@@ -440,7 +442,7 @@
} else if(fd.getName().equalsIgnoreCase(FunctionLibrary.LOOKUP)) {
ResolverUtil.ResolvedLookup lookup = ResolverUtil.resolveLookup(function, metadata);
fd = library.copyFunctionChangeReturnType(fd, lookup.getReturnElement().getType());
- } else if(fd.getName().equalsIgnoreCase(FunctionLibrary.XPATHVALUE)) {
+ } else if(fd.getName().equalsIgnoreCase(SourceSystemFunctions.XPATHVALUE)) {
// Validate the xpath value is valid
if(args[1] != null && args[1] instanceof Constant) {
Constant xpathConst = (Constant) args[1];
Modified:
trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/SQLStringVisitor.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/SQLStringVisitor.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/SQLStringVisitor.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -29,6 +29,7 @@
import java.util.LinkedList;
import java.util.List;
+import org.teiid.connector.api.SourceSystemFunctions;
import org.teiid.connector.language.SQLReservedWords;
import org.teiid.connector.language.SQLReservedWords.Tokens;
@@ -1245,6 +1246,22 @@
}
parts.add(")"); //$NON-NLS-1$
+ } else if (name.equalsIgnoreCase(SourceSystemFunctions.XSLTRANSFORM)){
+ parts.add(name);
+ parts.add("("); //$NON-NLS-1$
+
+ parts.add(registerNode(args[0]));
+ parts.add(SPACE);
+ parts.add(SQLReservedWords.USING);
+ parts.add(SPACE);
+ parts.add(registerNode(args[1]));
+ if (args.length > 2) {
+ parts.add(SPACE);
+ parts.add(SQLReservedWords.AS);
+ parts.add(SPACE);
+ parts.add(((Constant)args[2]).getValue());
+ }
+ parts.add(")"); //$NON-NLS-1$
} else {
parts.add(name);
parts.add("("); //$NON-NLS-1$
Modified: trunk/engine/src/main/java/com/metamatrix/query/util/CommandContext.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/util/CommandContext.java 2010-05-03
17:07:09 UTC (rev 2091)
+++ trunk/engine/src/main/java/com/metamatrix/query/util/CommandContext.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -101,6 +101,8 @@
private QueryMetadataInterface metadata;
private boolean validateXML;
+
+ private BufferManager bufferManager;
}
private GlobalState globalState = new GlobalState();
@@ -446,5 +448,13 @@
public boolean validateXML() {
return globalState.validateXML;
}
+
+ public BufferManager getBufferManager() {
+ return globalState.bufferManager;
+ }
+
+ public void setBufferManager(BufferManager bm) {
+ globalState.bufferManager = bm;
+ }
}
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java 2010-05-03
17:07:09 UTC (rev 2091)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -72,7 +72,6 @@
import com.metamatrix.query.processor.QueryProcessor;
import com.metamatrix.query.processor.TempTableDataManager;
import com.metamatrix.query.processor.xml.XMLPlan;
-import com.metamatrix.query.processor.xml.XMLPostProcessor;
import com.metamatrix.query.processor.xquery.XQueryPlan;
import com.metamatrix.query.resolver.QueryResolver;
import com.metamatrix.query.rewriter.QueryRewriter;
@@ -86,7 +85,6 @@
import com.metamatrix.query.sql.lang.XQuery;
import com.metamatrix.query.sql.symbol.Constant;
import com.metamatrix.query.sql.symbol.Reference;
-import com.metamatrix.query.sql.symbol.SingleElementSymbol;
import com.metamatrix.query.sql.visitor.ReferenceCollectorVisitor;
import com.metamatrix.query.tempdata.TempTableStore;
import com.metamatrix.query.util.CommandContext;
@@ -268,6 +266,7 @@
context.setTempTableStore(tempTableStore);
context.setQueryProcessorFactory(this);
context.setMetadata(this.metadata);
+ context.setBufferManager(this.bufferManager);
}
protected void checkReferences(List<Reference> references) throws
QueryValidatorException {
@@ -466,27 +465,13 @@
}
private void postProcessXML() {
- boolean alreadyFormatted = false;
if (requestMsg.getXMLFormat() != null) {
if(processPlan instanceof XQueryPlan) {
((XQueryPlan)processPlan).setXMLFormat(requestMsg.getXMLFormat());
- alreadyFormatted = true;
} else if (processPlan instanceof XMLPlan) {
((XMLPlan)processPlan).setXMLFormat(requestMsg.getXMLFormat());
- alreadyFormatted = true;
}
}
- boolean xml = alreadyFormatted
- || (processPlan.getOutputElements().size() == 1 &&
DataTypeManager.DefaultDataClasses.XML.equals(((SingleElementSymbol)processPlan.getOutputElements().get(0)).getType()));
-
- if (xml && ((!alreadyFormatted && requestMsg.getXMLFormat() !=
null) || requestMsg.getStyleSheet() != null)) {
- XMLPostProcessor postProcessor = new XMLPostProcessor(processPlan);
- postProcessor.setStylesheet(requestMsg.getStyleSheet());
- if (!alreadyFormatted) {
- postProcessor.setXMLFormat(requestMsg.getXMLFormat());
- }
- this.processPlan = postProcessor;
- }
this.context.setValidateXML(requestMsg.getValidationMode());
}
Modified: trunk/engine/src/main/resources/com/metamatrix/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/com/metamatrix/query/i18n.properties 2010-05-03
17:07:09 UTC (rev 2091)
+++ trunk/engine/src/main/resources/com/metamatrix/query/i18n.properties 2010-05-03
17:13:39 UTC (rev 2092)
@@ -767,6 +767,10 @@
SystemSource.xpath_param1=Source document
SystemSource.xpath_param2=XPath expression
SystemSource.xpath_result=XPath result
+SystemSource.xsltransform_description=Transform the document with the given stylesheet.
+SystemSource.xsltransform_param1=Source document
+SystemSource.xsltransform_param2=XSL stylesheet
+SystemSource.xsltransform_result=Clob result
SystemSource.modifyTimeZone_description=Modify the time zone of this timestamp by adding
or subtracting time
SystemSource.modifyTimeZone_param1=Timestamp
SystemSource.modifyTimeZone_param2=Starting time zone
Modified:
trunk/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java
===================================================================
---
trunk/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/engine/src/test/java/com/metamatrix/query/function/TestFunctionLibrary.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -22,12 +22,7 @@
package com.metamatrix.query.function;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -47,12 +42,18 @@
import org.teiid.connector.language.SQLReservedWords;
import com.metamatrix.api.exception.query.FunctionExecutionException;
+import com.metamatrix.common.buffer.BufferManagerFactory;
+import com.metamatrix.common.types.ClobType;
import com.metamatrix.common.types.DataTypeManager;
+import com.metamatrix.common.types.SQLXMLImpl;
+import com.metamatrix.common.types.XMLType;
import com.metamatrix.common.util.TimestampWithTimezone;
+import com.metamatrix.core.util.ObjectConverterUtil;
import com.metamatrix.query.function.metadata.FunctionMethod;
import com.metamatrix.query.unittest.TimestampUtil;
import com.metamatrix.query.util.CommandContext;
+@SuppressWarnings("nls")
public class TestFunctionLibrary {
// These are just used as shorthand convenience to make unit tests more readable below
@@ -1326,6 +1327,17 @@
@Test public void testInvokeNull1() throws Exception {
helpInvokeMethod(SourceSystemFunctions.CONCAT, new Class[]
{DataTypeManager.DefaultDataClasses.STRING, DataTypeManager.DefaultDataClasses.STRING},
new Object[] { null, String.valueOf(1) }, null, null);
- }
+ }
+ @Test public void testInvokeXslTransform() throws Exception {
+ CommandContext c = new CommandContext();
+ c.setBufferManager(BufferManagerFactory.getStandaloneBufferManager());
+ ClobType result = (ClobType)helpInvokeMethod("xsltransform", new
Class[] {DataTypeManager.DefaultDataClasses.XML, DataTypeManager.DefaultDataClasses.XML},
+ new Object[] {new XMLType(new SQLXMLImpl("<?xml
version=\"1.0\" encoding=\"UTF-8\"?><Catalogs
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><...
ItemID=\"001\"><Name>Lamp</Name><Quantity>5</Quantity></Item></Items></Catalog></Catalogs>")),
+ new XMLType(new SQLXMLImpl("<?xml version=\"1.0\"
encoding=\"UTF-8\"?><xsl:stylesheet version=\"1.0\"
xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:t...
match=\"@*|node()\"><xsl:copy><xsl:apply-templates
select=\"@*|node()\"/></xsl:copy></xsl:template><xsl:template
match=\"Quantity\"/></xsl:stylesheet>"))}, c);
+
+ String xml = ObjectConverterUtil.convertToString(result.getCharacterStream());
+ assertEquals("<?xml version=\"1.0\"
encoding=\"UTF-8\"?><Catalogs
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><...
ItemID=\"001\"><Name>Lamp</Name></Item></Items></Catalog></Catalogs>",
xml);
+ }
+
}
Modified:
trunk/engine/src/test/java/com/metamatrix/query/processor/xml/TestXMLProcessor.java
===================================================================
---
trunk/engine/src/test/java/com/metamatrix/query/processor/xml/TestXMLProcessor.java 2010-05-03
17:07:09 UTC (rev 2091)
+++
trunk/engine/src/test/java/com/metamatrix/query/processor/xml/TestXMLProcessor.java 2010-05-03
17:13:39 UTC (rev 2092)
@@ -11874,33 +11874,6 @@
" </Items>\r\n" + //$NON-NLS-1$
" </Catalog>\r\n" + //$NON-NLS-1$
"</Catalogs>\r\n\r\n"; //$NON-NLS-1$
-
- ProcessorPlan plan = helpTestProcess("exec xmltest.vsp1()",
expectedDoc, metadata, dataMgr); //$NON-NLS-1$
- plan.reset();
- XMLPostProcessor postProcessor = new XMLPostProcessor(plan);
- postProcessor.setXMLFormat(XMLFormatConstants.XML_TREE_FORMAT);
- postProcessor.setStylesheet("<?xml version=\"1.0\"
encoding=\"UTF-8\"?><xsl:stylesheet version=\"1.0\"
xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:t...
match=\"@*|node()\"><xsl:copy><xsl:apply-templates
select=\"@*|node()\"/></xsl:copy></xsl:template><xsl:template
match=\"Quantity\"/></xsl:stylesheet>");
- expectedDoc =
- "<?xml version=\"1.0\"
encoding=\"UTF-8\"?>\r\n" + //$NON-NLS-1$
- "<Catalogs
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n... +
//$NON-NLS-1$
- " <Catalog>\r\n" + //$NON-NLS-1$
- " <Items>\r\n" + //$NON-NLS-1$
- " <Item ItemID=\"001\">\r\n" +
//$NON-NLS-1$
- " <Name>Lamp</Name>\r\n" +
//$NON-NLS-1$
- " \r\n" + //$NON-NLS-1$
- " </Item>\r\n" + //$NON-NLS-1$
- " <Item ItemID=\"002\">\r\n" +
//$NON-NLS-1$
- " <Name>Screwdriver</Name>\r\n" +
//$NON-NLS-1$
- " \r\n" + //$NON-NLS-1$
- " </Item>\r\n" + //$NON-NLS-1$
- " <Item ItemID=\"003\">\r\n" +
//$NON-NLS-1$
- " <Name>Goat</Name>\r\n" +
//$NON-NLS-1$
- " \r\n" + //$NON-NLS-1$
- " </Item>\r\n" + //$NON-NLS-1$
- " </Items>\r\n" + //$NON-NLS-1$
- " </Catalog>\r\n" + //$NON-NLS-1$
- "</Catalogs>\r\n\r\n"; //$NON-NLS-1$
- helpTestProcess(new String[] {expectedDoc}, dataMgr, postProcessor);
//$NON-NLS-1$
}
/**