Author: jdoyle
Date: 2009-09-10 11:05:24 -0400 (Thu, 10 Sep 2009)
New Revision: 1315
Added:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/BaseRequest.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPRequest.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPRequest.java
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/ResultProducer.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/XMLExecution.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/CriteriaDesc.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/ExecutionInfo.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/IDGeneratingXmlFilter.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/ParameterDescriptor.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/QueryAnalyzer.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/RequestGenerator.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/file/FileExecution.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPConnectorState.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPExecution.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPExecutor.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPExecution.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPExecutor.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/BaseStreamingExecution.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/ElementProcessor.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/StreamingResultsProducer.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/StreamingRowCollector.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xmlsource/soap/SecurityToken.java
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xmlsource/soap/ServiceOperation.java
trunk/connectors/connector-xml/src/test/java/com/metamatrix/connector/xml/base/TestCriteriaDesc.java
Log:
TEIID-816 TEIID 817
Fix for = criteria, NPE in the FileConnector, and a multiplicity problem with the HTTP and
SOAP Relational connectors. Added some generics.
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/ResultProducer.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/ResultProducer.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/ResultProducer.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -4,6 +4,13 @@
import org.teiid.connector.api.ConnectorException;
+
+/**
+ *
+ * Abstracts the source of XML Documents. Also provides an interface
+ * to handle multiple documents resulting from a single query.
+ *
+ */
public interface ResultProducer {
/**
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/XMLExecution.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/XMLExecution.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/XMLExecution.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -23,19 +23,39 @@
package com.metamatrix.connector.xml;
import org.teiid.connector.api.ConnectorException;
-import org.teiid.connector.api.Execution;
import org.teiid.connector.api.ExecutionContext;
import org.teiid.connector.api.ResultSetExecution;
-public interface XMLExecution extends Execution, ResultSetExecution {
+/**
+ * An XMLExecution is responsible for responding to a Query. Depending upon
+ * the query and the source of the XML, this can sometimes require multiple
+ * trips to the source system.
+ *
+ * For example, as SOAP service that converts temperature:
+ *
+ * int convertToFahrenheit(int degreesCelsius)
+ *
+ * might be modeled as a Table called TempConversion with a column for celsius
+ * of type int and a column for fahreneheit also of type int.
+ *
+ * when queried like this:
+ *
+ *
+ * SELECT fahrenheit FROM TempConversion WHERE celsius IN (40, 20)
+ *
+ * The XMLExecution has to make two calls to the service to create the correct
+ * result set. The multiple calls are abstracted within the ResultProducer.
+ *
+ */
+public interface XMLExecution extends ResultSetExecution {
public XMLConnection getConnection();
public ExecutionContext getExeContext();
/**
- * Gets all the InputStreams for a single ExecutionInfo instance.
- * This could be any number or streams and is implementation dependent.
+ * Gets all the ResultProducers for a single query.
+ * This could be any number or results and is implementation dependent.
* @return
* @throws ConnectorException
*/
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/CriteriaDesc.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/CriteriaDesc.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/CriteriaDesc.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -55,7 +55,7 @@
// structure,
// and to make the code more manageable
- private ArrayList m_values;
+ private List m_values;
private int m_currentIndexInValuesList = 0;
@@ -108,7 +108,7 @@
IQuery query) throws ConnectorException {
CriteriaDesc retVal = null;
- ArrayList values = parseCriteriaToValues(element, query);
+ List values = parseCriteriaToValues(element, query);
if (values.size() == 0) {
if (testForParam(element)) {
@@ -126,7 +126,7 @@
return retVal;
}
- private static void handleDefaultValue(Element element, ArrayList values) throws
ConnectorException {
+ private static void handleDefaultValue(Element element, List values) throws
ConnectorException {
Object defaultVal = element.getDefaultValue();
if (defaultVal != null) {
values.add(defaultVal);
@@ -154,7 +154,7 @@
/**
* @see
com.metamatrix.server.datatier.SynchConnectorConnection#submitRequest(java.lang.Object)
*/
- public CriteriaDesc(Element myElement, ArrayList myValues)
+ public CriteriaDesc(Element myElement, List myValues)
throws ConnectorException {
super(myElement);
@@ -305,7 +305,7 @@
}
}
- public ArrayList getValues() {
+ public List getValues() {
return m_values;
}
@@ -352,10 +352,6 @@
m_currentIndexInValuesList = 0;
}
- //complete rewrite of criteria parsing code.
- //Replaces String parsing with an evaluation of the atomic query structure
- // provided by the server
- //Thsi should be much more bulletproof and more easily supported
private static ArrayList parseCriteriaToValues(Element element, IQuery query) throws
ConnectorException {
String fullName = element.getFullName().trim().toUpperCase();
@@ -364,10 +360,8 @@
|| element.getSearchability() == TypeModel.SEARCHABLE_COMPARE) {
// Check and set criteria for the IData input
ICriteria criteria = query.getWhere();
- List criteriaList = LanguageUtil.separateCriteriaByAnd(criteria);
- Iterator criteriaIter = criteriaList.iterator();
- while (criteriaIter.hasNext()) {
- ICriteria criteriaSeg = (ICriteria) criteriaIter.next();
+ List<ICriteria> criteriaList =
LanguageUtil.separateCriteriaByAnd(criteria);
+ for(ICriteria criteriaSeg: criteriaList) {
if (criteriaSeg instanceof ICompareCriteria) {
ICompareCriteria compCriteria = (ICompareCriteria) criteriaSeg;
if (compCriteria.getOperator() == Operator.EQ) {
@@ -402,15 +396,7 @@
}
}
- private static boolean disableJoins = false;
-// private static boolean disableJoins = true;
private static void handleCompareCriteria(IExpression lExpr, IExpression rExpr,
String fullName, ArrayList parmPair) {
- //not supporting joins inside this connector
- if (disableJoins) {
- if ((lExpr instanceof IElement) && (rExpr instanceof IElement)) {
- return;
- }
- }
checkElement(lExpr, rExpr, fullName, parmPair);
checkElement(rExpr, lExpr, fullName, parmPair);
}
@@ -442,7 +428,7 @@
public static String stringifyCriteria(String startCriteria) {
int indx = 0;
- String cStr = new String(startCriteria);
+ String cStr = startCriteria;
indx = cStr.indexOf("'"); //$NON-NLS-1$
if (indx == 0) {
int indx2 = cStr.substring(1).indexOf("'"); //$NON-NLS-1$
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/ExecutionInfo.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/ExecutionInfo.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/ExecutionInfo.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -51,10 +51,9 @@
private List m_columns;
private int m_columnCount;
- private List m_params;
- private List m_criteria;
+ private List<CriteriaDesc> m_params;
+ private List<CriteriaDesc> m_criteria;
private Properties m_otherProps;
- private Properties m_schemaProps;
private String m_tablePath;
private String m_location;
private Map<String, String> m_prefixToNamespace;
@@ -63,10 +62,9 @@
public ExecutionInfo() {
m_columnCount = 0;
m_columns = new ArrayList();
- m_params = new ArrayList();
- m_criteria = new ArrayList();
+ m_params = new ArrayList<CriteriaDesc>();
+ m_criteria = new ArrayList<CriteriaDesc>();
m_otherProps = new Properties();
- m_schemaProps = new Properties();
m_tablePath = ""; //$NON-NLS-1$
}
@@ -90,12 +88,12 @@
}
- public List getParameters() {
+ public List<CriteriaDesc> getParameters() {
return m_params;
}
- public List getCriteria() {
+ public List<CriteriaDesc> getCriteria() {
return m_criteria;
}
@@ -127,12 +125,12 @@
}
- public void setParameters(List params) {
+ public void setParameters(List<CriteriaDesc> params) {
m_params = params;
}
- public void setCriteria(List criteria) {
+ public void setCriteria(List<CriteriaDesc> criteria) {
m_criteria = criteria;
}
@@ -213,12 +211,4 @@
return m_prefixToNamespace;
}
}
-
- public void setSchemaProperties(Properties schemaProperties) {
- m_schemaProps = schemaProperties;
- }
-
- public Properties getSchemaProperties() {
- return m_schemaProps;
- }
}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/IDGeneratingXmlFilter.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/IDGeneratingXmlFilter.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/IDGeneratingXmlFilter.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -53,7 +53,6 @@
public IDGeneratingXmlFilter(String documentId, ConnectorLogger logger)
{
this.documentId = documentId;
- this.logger = logger;
}
public static final String MM_ID_ATTR_NAME_BY_PATH =
"com.metamatrix.xml.xpathpart";
@@ -61,7 +60,6 @@
public static final String MM_ID_ATTR_NAME = MM_ID_ATTR_NAME_BY_PATH;
public static final String MM_ID_ATTR_VALUE_PREFIX = "";
- ConnectorLogger logger;
String documentId;
// This way of doing things seems like cheating, but it will produce the desired
results.
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/ParameterDescriptor.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/ParameterDescriptor.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/ParameterDescriptor.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -118,7 +118,7 @@
m_element = elem;
}
- protected Element getElement() {
+ public Element getElement() {
return m_element;
}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/QueryAnalyzer.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/QueryAnalyzer.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/QueryAnalyzer.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -26,7 +26,6 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import java.util.Properties;
import org.teiid.connector.api.ConnectorEnvironment;
import org.teiid.connector.api.ConnectorException;
@@ -35,6 +34,7 @@
import org.teiid.connector.language.IElement;
import org.teiid.connector.language.IExpression;
import org.teiid.connector.language.IFrom;
+import org.teiid.connector.language.IFromItem;
import org.teiid.connector.language.IGroup;
import org.teiid.connector.language.ILiteral;
import org.teiid.connector.language.IQuery;
@@ -64,9 +64,6 @@
private ExecutionContext exeContext;
- private Properties schemaProperties;
-
-
public QueryAnalyzer(IQuery query, RuntimeMetadata metadata, IQueryPreprocessor
preprocessor,
ConnectorLogger logger, ExecutionContext exeContext, ConnectorEnvironment
connectorEnv) throws ConnectorException {
setMetaData(metadata);
@@ -119,49 +116,27 @@
private void setGroupInfo() throws ConnectorException {
IFrom from = m_query.getFrom();
- List fromItems = from.getItems();
- //better be only one
+ List<IFromItem> fromItems = from.getItems();
+ //Can only be one because we do not support joins
IGroup group = (IGroup) fromItems.get(0);
m_table = group.getMetadataObject();
m_info.setTableXPath(m_table.getNameInSource());
-
- String fqTableName = m_table.getFullName();
- String fqSchemaName = extractSchemaName(fqTableName);
-
- if(null != fqSchemaName) {
- try{
- Group schema = m_metadata.getGroup(fqSchemaName);
- schemaProperties = schema.getProperties();
- } catch(ConnectorException ex) {
-
- }
- }
}
- private String extractSchemaName(String fqTableName) {
- int schemaEnd = fqTableName.lastIndexOf('.');
- int schemaStart = fqTableName.lastIndexOf('.', schemaEnd -1);
- if(-1 == schemaStart || -1 == schemaEnd) {
- return null;
- }
- return fqTableName.substring(schemaStart +1, schemaEnd);
- }
-
private void setRequestedColumns() throws ConnectorException {
- ArrayList columns = new ArrayList();
+ List<OutputXPathDesc> columns = new ArrayList<OutputXPathDesc>();
//get the request items
ISelect select = m_query.getSelect();
- List selectSymbols = select.getSelectSymbols();
- Iterator symbolsIterator = selectSymbols.iterator();
-
+ List<ISelectSymbol> selectSymbols = select.getSelectSymbols();
+
//setup column numbers
int projectedColumnCount = 0;
//add projected fields into XPath array and element array for later
// lookup
- while (symbolsIterator.hasNext()) {
- ISelectSymbol selectSymbol = (ISelectSymbol) symbolsIterator.next();
+
+ for(ISelectSymbol selectSymbol : selectSymbols) {
IExpression expr = selectSymbol.getExpression();
OutputXPathDesc xpath = null;
@@ -193,10 +168,10 @@
// containing names, element (metadata), and equivilence value, or all
// set values
- ArrayList params = new ArrayList();
- ArrayList crits = new ArrayList();
- ArrayList responses = new ArrayList();
- ArrayList locations = new ArrayList();
+ ArrayList<CriteriaDesc> params = new ArrayList<CriteriaDesc>();
+ ArrayList<CriteriaDesc> crits = new ArrayList<CriteriaDesc>();
+ ArrayList<CriteriaDesc> responses = new ArrayList<CriteriaDesc>();
+ ArrayList<CriteriaDesc> locations = new ArrayList<CriteriaDesc>();
//Iterate through each field in the table
for (Element element : m_table.getChildren()) {
@@ -210,10 +185,10 @@
m_info.setCriteria(crits);
String location = null;
- for (Iterator iter = locations.iterator(); iter.hasNext(); ) {
+ for (Iterator<CriteriaDesc> iter = locations.iterator(); iter.hasNext(); )
{
Object o = iter.next();
CriteriaDesc crtierion = (CriteriaDesc)o;
- ArrayList values = crtierion.getValues();
+ List values = crtierion.getValues();
for (Iterator valuesIter = values.iterator(); valuesIter.hasNext(); ) {
Object oValue = valuesIter.next();
String value = (String)oValue;
@@ -229,8 +204,8 @@
m_info.setLocation(location);
}
- private void mapCriteriaToColumn(CriteriaDesc criteria, ArrayList params,
- ArrayList crits, ArrayList responses, ArrayList locations) throws
ConnectorException {
+ private void mapCriteriaToColumn(CriteriaDesc criteria, ArrayList<CriteriaDesc>
params,
+ ArrayList<CriteriaDesc> crits, ArrayList<CriteriaDesc> responses,
ArrayList<CriteriaDesc> locations) throws ConnectorException {
int totalColumnCount = m_info.getColumnCount();
//check each criteria to see which projected column it maps to
String criteriaColName = criteria.getColumnName();
@@ -278,11 +253,10 @@
private void setProperties() throws ConnectorException {
m_info.setOtherProperties(m_table.getProperties());
- m_info.setSchemaProperties(schemaProperties);
}
- public List getRequestPerms() {
- return RequestGenerator.getRequestPerms(m_info.getParameters());
+ public List<CriteriaDesc[]> getRequestPerms() {
+ return RequestGenerator.getRequests(m_info.getParameters());
}
}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/RequestGenerator.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/RequestGenerator.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/base/RequestGenerator.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -25,23 +25,19 @@
package com.metamatrix.connector.xml.base;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
public class RequestGenerator {
// This method is misnamed. It generates cartesian products, not permutations.
- public static ArrayList getRequestPerms(List params)
+ public static List<CriteriaDesc[]> getRequests(List<CriteriaDesc> params)
{
- ArrayList soFar = new ArrayList();
+ List<CriteriaDesc[]> soFar = new ArrayList<CriteriaDesc[]>();
// Start off with a single "row" (with zero parameters)
soFar.add(new CriteriaDesc[]{});
- for (Iterator iter = params.iterator(); iter.hasNext(); ) {
- Object o = iter.next();
- CriteriaDesc desc = (CriteriaDesc)o;
- ArrayList nextGeneration = RequestGenerator.createCartesionProduct(soFar,
desc);
- soFar = nextGeneration;
+ for (CriteriaDesc desc: params){
+ soFar = RequestGenerator.createCartesionProduct(soFar, desc);
}
return soFar;
@@ -49,17 +45,15 @@
// Create the cartesian product of a list of CriteriaDescs, and single CriteriaDesc
// with (potentially) multiple values
- static ArrayList createCartesionProduct(List permsSoFar, CriteriaDesc desc)
+ static List<CriteriaDesc[]> createCartesionProduct(List<CriteriaDesc[]>
permsSoFar, CriteriaDesc desc)
{
- ArrayList retval = new ArrayList();
+ List<CriteriaDesc[]> retval = new ArrayList<CriteriaDesc[]>();
// Get the 'simple' cartesian product
- List rows = createCartesionProduct(permsSoFar, desc.getValues(), desc.isUnlimited());
+ List<List> rows = createCartesionProduct(permsSoFar, desc.getValues(),
desc.isUnlimited());
// Merge the existing list of CriteriaDescs with the new value turned into a
CriteriaDesc)
- for (Iterator iter = rows.iterator(); iter.hasNext(); ) {
- Object oRow = iter.next();
- ArrayList row = (ArrayList)oRow;
+ for (List row : rows) {
Object oOperand1 = row.get(0);
CriteriaDesc[] previousCriteriaDescs = (CriteriaDesc[])oOperand1;
@@ -77,10 +71,10 @@
}
// Create the cartesian product of any two lists
- private static List createCartesionProduct(List operand1, List operand2, boolean
multiElem)
+ private static List<List> createCartesionProduct(List<CriteriaDesc[]>
operand1, List operand2, boolean multiElem)
{
if (operand1.size() == 0) {
- operand1 = new ArrayList();
+ operand1 = new ArrayList<CriteriaDesc[]>();
operand1.add(null);
}
@@ -90,25 +84,19 @@
}
- ArrayList cartesianProduct = new ArrayList();
- for (Iterator operand1iter = operand1.iterator(); operand1iter.hasNext(); ) {
- Object operand1item = operand1iter.next();
-
+ List<List> cartesianProduct = new ArrayList<List>();
+ for (CriteriaDesc[] operand1item : operand1) {
+ List newRow = new ArrayList();
if (! multiElem) {
- for (Iterator operand2iter = operand2.iterator(); operand2iter.hasNext(); ) {
- Object operand2item = operand2iter.next();
-
- ArrayList newRow = new ArrayList();
- newRow.add(operand1item);
- newRow.add(operand2item);
- cartesianProduct.add(newRow);
+ for (Object operand2item : operand2 ) {
+ newRow.add(operand1item);
+ newRow.add(operand2item);
+ cartesianProduct.add(newRow);
}
} else {
- ArrayList newRow = new ArrayList();
newRow.add(operand1item);
- for (Iterator operand2iter = operand2.iterator(); operand2iter.hasNext(); ) {
- Object operand2item = operand2iter.next();
- newRow.add(operand2item);
+ for (Object operand2item : operand2 ) {
+ newRow.add(operand2item);
}
cartesianProduct.add(newRow);
}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/file/FileExecution.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/file/FileExecution.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/file/FileExecution.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -54,7 +54,7 @@
exeInfo = analyzer.getExecutionInfo();
init(); // depends upon the creation of m_info
validateParams();
- List requestPerms = analyzer.getRequestPerms();
+ List<CriteriaDesc[]> requestPerms = analyzer.getRequestPerms();
if (requestPerms.size() > 1) {
throw new AssertionError(
@@ -177,13 +177,31 @@
if (path.endsWith(File.separator)) {
return path;
} else {
- return new String(path + File.separator);
+ return path + File.separator;
}
}
/////////////////////////
// End Initialization
/////////////////////////
+ public ExecutionInfo getInfo() {
+ return exeInfo;
+ }
+
+ @Override
+ public ResultProducer getStreamProducer() throws ConnectorException {
+ return this;
+ }
+
+ public Iterator<Document> getXMLDocuments() throws ConnectorException {
+ return new XMLFileIterator(state.getDirectoryPath());
+ }
+
+ @Override
+ public void closeStreams() {
+ // Nothing to do
+ }
+
private class XMLFileIterator implements Iterator<Document> {
private String queryID;
@@ -224,7 +242,7 @@
private Document getDocument() throws ConnectorException {
Document doc;
- String cacheKey = queryID + new Integer(docNumber).toString();
+ String cacheKey = queryID + Integer.valueOf(docNumber).toString();
if(state.isCaching()) {
if(null != exeContext.get(queryID)) {
InputStream stream = new CachedXMLStream(exeContext, queryID);
@@ -259,22 +277,4 @@
}
}
-
- public ExecutionInfo getInfo() {
- return exeInfo;
- }
-
- @Override
- public ResultProducer getStreamProducer() throws ConnectorException {
- return this;
- }
-
- public Iterator<Document> getXMLDocuments() throws ConnectorException {
- return new XMLFileIterator(state.getDirectoryPath());
- }
-
- @Override
- public void closeStreams() {
- // Nothing to do
- }
}
Added:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/BaseRequest.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/BaseRequest.java
(rev 0)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/BaseRequest.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -0,0 +1,65 @@
+package com.metamatrix.connector.xml.http;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+
+import org.teiid.connector.api.ConnectorException;
+
+import com.metamatrix.connector.xml.XMLExecution;
+import com.metamatrix.connector.xml.base.CriteriaDesc;
+import com.metamatrix.connector.xml.base.ExecutionInfo;
+
+public abstract class BaseRequest {
+
+ protected String uriString;
+ protected HTTPConnectorState state;
+ protected ExecutionInfo exeInfo;
+ protected XMLExecution execution;
+ protected List<CriteriaDesc> parameters;
+
+ BaseRequest(HTTPConnectorState state , XMLExecution execution, ExecutionInfo exeInfo,
List<CriteriaDesc> parameters) {
+ this.state = state;
+ this.execution = execution;
+ this.exeInfo = exeInfo;
+ this.parameters = parameters;
+ }
+
+ abstract protected void initialize() throws ConnectorException;
+
+ protected String getUriString() {
+ if(null != uriString) {
+ return uriString;
+ } else {
+ uriString = "<" + buildRawUriString() + ">";
//$NON-NLS-1$
+ return uriString;
+ }
+ }
+
+ protected String buildRawUriString() {
+ String location = exeInfo.getLocation();
+ if (location != null) {
+ // If the location is a URL, it replaces the full URL (first part
+ // set in the
+ // connector binding and second part set in the model).
+ try {
+ new URL(location);
+ return location;
+ } catch (MalformedURLException e) {
+ }
+ }
+
+ if (location == null) {
+ final String tableServletCallPathProp = "ServletCallPathforURL";
//$NON-NLS-1$
+ location = this.exeInfo.getOtherProperties().getProperty(
+ tableServletCallPathProp);
+ }
+
+ String retval = state.getUri();
+ if (location != null && location.trim().length() > 0) {
+ retval = retval + "/" + location; //$NON-NLS-1$
+ }
+ return retval;
+ }
+
+}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPConnectorState.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPConnectorState.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPConnectorState.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -131,8 +131,8 @@
m_connMgrParams = null;
m_client = null;
setUseHttpBasicAuth(false);
- setHttpBasicAuthUser(new String());
- setHttpBasicAuthPwd(new String());
+ setHttpBasicAuthUser("");
+ setHttpBasicAuthPwd("");
}
@Override
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPExecution.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPExecution.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPExecution.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -23,10 +23,6 @@
package com.metamatrix.connector.xml.http;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
import org.teiid.connector.api.ConnectorEnvironment;
import org.teiid.connector.api.ConnectorException;
import org.teiid.connector.api.ExecutionContext;
@@ -35,7 +31,6 @@
import com.metamatrix.connector.xml.ResultProducer;
import com.metamatrix.connector.xml.XMLConnectorState;
-import com.metamatrix.connector.xml.base.CriteriaDesc;
import com.metamatrix.connector.xml.base.QueryAnalyzer;
import com.metamatrix.connector.xml.base.XMLConnectionImpl;
import com.metamatrix.connector.xml.streaming.BaseStreamingExecution;
@@ -45,13 +40,15 @@
public class HTTPExecution extends BaseStreamingExecution {
- public HTTPExecution(IQuery query, XMLConnectionImpl conn, RuntimeMetadata metadata,
+ protected QueryAnalyzer analyzer;
+
+ public HTTPExecution(IQuery query, XMLConnectionImpl conn, RuntimeMetadata metadata,
ExecutionContext exeContext, ConnectorEnvironment connectorEnv) {
super(query, conn, metadata, exeContext, connectorEnv);
}
/**
- * HTTP execution can have multiple permutations from a single SQL
+ * HTTP execution can produce multiple requests from a single SQL
* query, but each will have only one response.
*/
public void execute()
@@ -59,12 +56,22 @@
XMLConnectorState state = connection.getState();
- QueryAnalyzer analyzer = new QueryAnalyzer(query, metadata,
state.getPreprocessor(), logger, exeContext, connEnv);
+ analyzer = new QueryAnalyzer(query, metadata, state.getPreprocessor(), logger,
exeContext, connEnv);
exeInfo = analyzer.getExecutionInfo();
- List requestPerms = analyzer.getRequestPerms();
+ rowProducer = new StreamingResultsProducer(exeInfo, state);
+ resultProducers.add(getStreamProducer());
- for (Iterator iter = requestPerms.iterator(); iter.hasNext(); ) {
- List<CriteriaDesc> criteriaList = Arrays.asList((CriteriaDesc[])
iter.next());
+ XPathSplitter splitter = new XPathSplitter();
+ try {
+ xpaths = splitter.split(exeInfo.getTableXPath());
+ } catch (InvalidPathException e) {
+ e.printStackTrace();
+ }
+/*
+ List<CriteriaDesc[]> requestPerms = analyzer.getRequestPerms();
+
+ for (CriteriaDesc[] criteria : requestPerms) {
+ List<CriteriaDesc> criteriaList = Arrays.asList(criteria);
exeInfo.setParameters(criteriaList);
XPathSplitter splitter = new XPathSplitter();
@@ -77,10 +84,11 @@
rowProducer = new StreamingResultsProducer(exeInfo, state);
resultProducers.add(getStreamProducer());
}
+*/
}
@Override
public ResultProducer getStreamProducer() throws ConnectorException {
- return new HTTPExecutor(connection.getState(), this, exeInfo);
+ return new HTTPExecutor((HTTPConnectorState) connection.getState(), this, exeInfo,
analyzer);
}
}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPExecutor.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPExecutor.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPExecutor.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -23,648 +23,75 @@
package com.metamatrix.connector.xml.http;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLEncoder;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
-import java.util.Properties;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.NameValuePair;
-import org.apache.commons.httpclient.URIException;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.StringRequestEntity;
-import org.apache.commons.httpclient.util.ParameterParser;
-import org.jdom.Document;
import org.teiid.connector.api.ConnectorException;
-import org.teiid.connector.api.ConnectorLogger;
-import org.teiid.connector.api.ExecutionContext;
-import com.metamatrix.connector.xml.CachingConnector;
-import com.metamatrix.connector.xml.Constants;
import com.metamatrix.connector.xml.ResultProducer;
-import com.metamatrix.connector.xml.SAXFilterProvider;
-import com.metamatrix.connector.xml.XMLConnection;
-import com.metamatrix.connector.xml.XMLConnectorState;
import com.metamatrix.connector.xml.XMLExecution;
import com.metamatrix.connector.xml.base.CriteriaDesc;
-import com.metamatrix.connector.xml.base.DocumentBuilder;
import com.metamatrix.connector.xml.base.ExecutionInfo;
-import com.metamatrix.connector.xml.base.LoggingInputStreamFilter;
-import com.metamatrix.connector.xml.base.OutputXPathDesc;
-import com.metamatrix.connector.xml.base.ParameterDescriptor;
-import com.metamatrix.connector.xml.base.RequestGenerator;
-import com.metamatrix.connector.xml.cache.CachedXMLStream;
-import com.metamatrix.connector.xml.streaming.DocumentImpl;
+import com.metamatrix.connector.xml.base.QueryAnalyzer;
public class HTTPExecutor implements ResultProducer {
protected XMLExecution execution;
+
+ protected List<HTTPRequest> requests = new ArrayList<HTTPRequest>();
- protected HTTPRequestor m_requestor;
+ protected HTTPConnectorState state;
- protected HttpMethod request;
+ protected ExecutionInfo exeInfo;
- private HTTPConnectorState state;
-
- private boolean m_allowHttp500;
-
- private ExecutionInfo exeInfo;
-
- public static final String PARM_INPUT_XPATH_TABLE_PROPERTY_NAME =
"XPathRootForInput"; //$NON-NLS-1$
-
- public static final String PARM_INPUT_NAMESPACE_TABLE_PROPERTY_NAME =
"NamespaceForDocument"; //$NON-NLS-1$
-
/**
* @param state
* @param execution
* @param exeInfo
+ * @param analyzer
* @throws ConnectorException
*/
- public HTTPExecutor(XMLConnectorState state, XMLExecution execution, ExecutionInfo
exeInfo)
+ public HTTPExecutor(HTTPConnectorState state, XMLExecution execution, ExecutionInfo
exeInfo, QueryAnalyzer analyzer)
throws ConnectorException {
this.execution = execution;
- this.setExeInfo(exeInfo);
- this.setState((HTTPConnectorState) state);
- processOutputXPathDescs(getExeInfo().getRequestedColumns()
- , getExeInfo().getParameters());
- m_requestor = new HTTPRequestor(getLogger(), getState().getAccessMethod());
- setAllowHttp500(false);
- try {
- String uri = buildRawUriString();
- m_requestor.validateURL(uri);
- } catch (IOException ioe) {
- throw new ConnectorException(ioe);
- }
- getLogger()
- .logDetail(Messages.getString("HTTPExecutor.url.validated"));
//$NON-NLS-1$
+ this.exeInfo = exeInfo;
+ this.state = state;
+
+ List<CriteriaDesc[]> requestPerms = analyzer.getRequestPerms();
+
+ createRequests(execution, exeInfo, requestPerms);
}
- protected void releaseDocumentStream() {
- if (request != null) {
- request.releaseConnection();
- request = null;
- }
- }
-
- protected String getCacheKey() throws ConnectorException {
-
- if (request == null) {
- String message = com.metamatrix.connector.xml.http.Messages
- .getString("HttpExecutor.cannot.create.cachekey");
- throw new ConnectorException(message);
- }
- // the key consists of a String in the form of
- // |uri|parameterList|
- String userName = execution.getConnection().getUser();
- String session = execution.getConnection().getQueryId();
-
- StringBuffer cacheKey = new StringBuffer();
- cacheKey.append("|"); //$NON-NLS-1$
- cacheKey.append(userName);
- cacheKey.append("|");
- cacheKey.append(session);
- cacheKey.append("|");
- cacheKey.append(buildUriString());
- cacheKey.append("|"); //$NON-NLS-1$
-
- if (request instanceof PostMethod) {
- NameValuePair[] pairs = ((PostMethod) request).getParameters();
- if (pairs == null || pairs.length == 0) {
- if (((PostMethod) request).getRequestEntity() != null) {
- String requestBodyAsString = ((StringRequestEntity) (((PostMethod)
request)
- .getRequestEntity())).getContent();
- cacheKey.append(requestBodyAsString);
- }
- } else {
- cacheKey.append(generatePairString(pairs));
- }
- } else {
- cacheKey.append(request.getQueryString());
- }
- return cacheKey.toString();
- }
-
- protected InputStream getDocumentStream() throws ConnectorException {
- HttpClient client = (getState()).getClient();
- XMLConnection conn = execution.getConnection();
- try {
- HTTPTrustDeserializer ser = (HTTPTrustDeserializer) conn
- .getTrustedPayloadHandler();
- ser.modifyRequest(client, request);
- } catch (ClassCastException cce) {
- throw new ConnectorException(
- com.metamatrix.connector.xml.http.Messages
-
.getString("HTTPExecutor.class.not.instance.of.HTTPTrustDeserializer"));
- } catch (Exception e) {
- ConnectorException ce = new ConnectorException(
- com.metamatrix.connector.xml.http.Messages
-
.getString("HTTPExecutor.unable.to.create.trust.deserializer"));
- ce.setStackTrace(e.getStackTrace());
- throw ce;
- }
- modifyRequest(client, request);
- InputStream responseBody = m_requestor.fetchXMLDocument(client,
- request, getAllowHttp500());
- return responseBody;
- }
-
@Override
public Iterator<com.metamatrix.connector.xml.Document> getXMLDocuments() throws
ConnectorException {
ArrayList<com.metamatrix.connector.xml.Document> result = new
ArrayList<com.metamatrix.connector.xml.Document>();
- createRequests();
- CachingConnector connector = execution.getConnection().getConnector();
- ExecutionContext exeContext = execution.getExeContext();
- String cacheKey = getCacheKey();
-
-
- // Is this a request part joining across a document
- CriteriaDesc criterion = getExeInfo().getResponseIDCriterion();
- if (null != criterion) {
- String responseid = (String) (criterion.getValues().get(0));
-
- if(null == exeContext.get(responseid)) {
- throw new
ConnectorException(Messages.getString("HTTPExecutor.No.doc.in.cache"));
- } else {
- InputStream stream = new CachedXMLStream(exeContext, responseid);
- com.metamatrix.connector.xml.Document doc = new DocumentImpl(stream,
cacheKey);
- result.add(doc);
- }
+
+ for(HTTPRequest request : requests) {
+ com.metamatrix.connector.xml.Document doc = request.getDocumentStream();
+ result.add(doc);
}
-
- // Not a join, but might still be cached.
- if (null == exeContext.get(cacheKey)) {
- SAXFilterProvider provider = null;
- provider = getState().getSAXFilterProvider();
- InputStream responseBody = getDocumentStream();
- InputStream filteredStream = addStreamFilters(responseBody,
getLogger());
- com.metamatrix.connector.xml.Document doc = new
DocumentImpl(filteredStream, cacheKey);
- result.add(doc);
- }
return result.iterator();
+
}
-
- private void createRequests() throws ConnectorException {
- if (checkIfRequestIsNeeded(getExeInfo())) {
- String uriString = buildUriString();
- setRequests(getExeInfo().getParameters(), uriString);
- }
- }
-
- protected void modifyRequest(HttpClient client, HttpMethod method)
- throws ConnectorException {
- // to be overridden by subclasses
- }
-
- public boolean cannotProjectParameter(CriteriaDesc parmCriteria) {
- return parmCriteria.getNumberOfValues() > 1
- && parmCriteria.isUnlimited()
- && !((getState()).getParameterMethod() ==
HTTPConnectorState.PARAMETER_NAME_VALUE);
- }
-
- // this routine builds the input XML document using JDOM structures
- protected Document buildInputXMLDocument(List parameters,
- String inputParmsXPath) throws ConnectorException {
- String namespacePrefixes = getExeInfo().getOtherProperties()
- .getProperty(Constants.NAMESPACE_PREFIX_PROPERTY_NAME);
- DocumentBuilder builder = new DocumentBuilder();
- return builder.buildDocument(parameters, inputParmsXPath,
- namespacePrefixes);
- }
-
- protected NameValuePair[] createNameValuePairs(List paramPairs)
- throws ConnectorException {
- NameValuePair[] pairs = new NameValuePair[paramPairs.size()];
- for (int i = 0; i < pairs.length; i++) {
- CriteriaDesc cd = (CriteriaDesc) paramPairs.get(i);
- String name = (cd.getInputXpath() == null || cd.getInputXpath()
- .length() == 0) ? cd.getColumnName() : cd.getInputXpath();
- NameValuePair pair = new NameValuePair(name, cd
- .getCurrentIndexValue());
- pairs[i] = pair;
- }
-
- return pairs;
- }
-
- protected void setRequests(List params, String bindingURIValue)
- throws ConnectorException {
-
- String xmlDoc = null;
- // see if there are parameters to set
- if (getState().getParameterMethod() == HTTPConnectorState.PARAMETER_NONE
- || params.size() == 0) {
- getLogger()
- .logTrace("XML Connector Framework: no parameters for
request"); //$NON-NLS-1$
- }
- // mrh: Originally HTTP and SOAP did the creation of multiple requests
- // from IN criteria
- // themselves, but that has been moved to the base code. So
- // XMLExecutionImpl.getRequestPerms
- // will now always return just one permutation. However, 'requestPerms'
- // is a different
- // structure than 'params' so I won't refactor that just yet.
- List requestPerms = RequestGenerator.getRequestPerms(params);
-
- for (int i = 0; i < requestPerms.size(); i++) {
- NameValuePair[] pairs = null;
- String bindingURI = null;
- String bindingQueryString = null;
- if(-1 != bindingURIValue.indexOf('?')) {
- bindingURI = bindingURIValue.substring(1,
bindingURIValue.indexOf('?'));
- bindingQueryString =
bindingURIValue.substring(bindingURIValue.indexOf('?') + 1,
bindingURIValue.length() -1);
- } else {
- bindingURI = bindingURIValue;
- }
-
- if(-1 != bindingURI.indexOf("<") || -1 !=
bindingURI.indexOf("<")) {
- bindingURI = removeAngleBrackets(bindingURI);
- }
-
- CriteriaDesc[] queryParameters = (CriteriaDesc[]) requestPerms
- .get(i);
- java.util.List newList = java.util.Arrays.asList(queryParameters);
- List queryList = new ArrayList(newList);
-
- String parameterMethod = getState().getParameterMethod();
- if (parameterMethod == HTTPConnectorState.PARAMETER_XML_REQUEST ||
- parameterMethod == HTTPConnectorState.PARAMETER_XML_QUERY_STRING ) {
- xmlDoc = createXMLRequestDocString(queryList);
- String paramName = getState().getXmlParameterName();
- if(null != paramName) {
- pairs = new NameValuePair[] { new NameValuePair(getState()
- .getXmlParameterName(), xmlDoc) };
- if (pairs != null) {
- attemptConditionalLog("XML Connector Framework: request
parameters -\n "
- + generatePairString(pairs));
- }
- }
- } else if (parameterMethod == HTTPConnectorState.PARAMETER_NAME_VALUE ||
- parameterMethod == HTTPConnectorState.PARAMETER_NONE) {
- pairs = createNameValuePairs(queryList);
- }
-
- HttpMethod method = null;
- String accessMethod = getState().getAccessMethod();
- if(accessMethod.equals(HTTPConnectorState.POST)) {
- method = m_requestor.generateMethod(bindingURI);
- PostMethod post = (PostMethod) method;
- if (pairs == null) {
- //POST-DOC-NO_PARAM_NAME
- if(bindingQueryString != null) {
- pairs = getPairsFromQueryString(xmlDoc, bindingQueryString);
- post.addParameters(pairs);
- attemptConditionalLog("XML Connector Framework: request
parameters -\n " + generatePairString(pairs)); //$NON-NLS-1$
- } else {
- post.setRequestEntity(new StringRequestEntity(xmlDoc));
- attemptConditionalLog("XML Connector Framework: request body
set to: " + xmlDoc); //$NON-NLS-1$
- }
- } else {
- //POST-DOC-WITH_PARAM_NAME
- if(parameterMethod == HTTPConnectorState.PARAMETER_XML_QUERY_STRING)
{
- //QUERY_STRING
- StringBuffer requestEntity = new StringBuffer();
- if(null != bindingQueryString) {
- requestEntity.append(bindingQueryString);
- requestEntity.append('&');
- }
- requestEntity.append(getState().getXmlParameterName());
- requestEntity.append('=');
- requestEntity.append(xmlDoc);
- URI realURI = null;
- try {
- realURI = new URI(bindingURI + "?" +
URLEncoder.encode(requestEntity.toString()));
- String fullQueryString = realURI.toString();
- method = m_requestor.generateMethod(fullQueryString);
- attemptConditionalLog("XML Connector Framework: request
set to -\n " + fullQueryString); //$NON-NLS-1$
- } catch (URISyntaxException e) {
- throw new ConnectorException(e.getMessage());
- }
- } else {
- //XML_REQUEST
- if(null != bindingQueryString){
- NameValuePair[] bindingPairs =
getPairsFromQueryString(xmlDoc, bindingQueryString);
- pairs = combinePairArrays(pairs, bindingPairs);
- }
- post.addParameters(pairs);
- attemptConditionalLog("XML Connector Framework: request
parameters -\n " + generatePairString(pairs)); //$NON-NLS-1$
- }
- }
- } else if (accessMethod.equals(HTTPConnectorState.GET)){
- method = m_requestor.generateMethod(bindingURI);
- if (pairs == null) {
- throw new ConnectorException(
- com.metamatrix.connector.xml.http.Messages
-
.getString("HTTPExecutor.parameter.name.required.for.get")); //$NON-NLS-1$
- }
- if(null != bindingQueryString){
- NameValuePair[] bindingPairs = getPairsFromQueryString(xmlDoc,
bindingQueryString);
- pairs = combinePairArrays(pairs, bindingPairs);
- }
- addGetValues(pairs, method);
- attemptConditionalLog("XML Connector Framework: request paramters
-\n " + generatePairString(pairs)); //$NON-NLS-1$
-
- }
- request = method;
- getLogger().logInfo("XML Connector Framework: request created");
//$NON-NLS-1$
- }
- }
-
- protected void addGetValues(NameValuePair[] pairs, HttpMethod method)
- throws ConnectorException {
- method.setQueryString(pairs);
- }
-
- protected void addPostValues(NameValuePair[] pairs, PostMethod method)
- throws ConnectorException {
- method.addParameters(pairs);
- }
-
- protected Document createXMLRequestDoc(List parameterPairs)
- throws ConnectorException {
- Properties props = getExeInfo().getOtherProperties();
- String inputParmsXPath = props
- .getProperty(PARM_INPUT_XPATH_TABLE_PROPERTY_NAME);
- Document inputXMLDoc = buildInputXMLDocument(parameterPairs,
- inputParmsXPath);
- return inputXMLDoc;
- }
-
- protected String createXMLRequestDocString(List parameterPairs)
- throws ConnectorException {
- Document inputXMLDoc = createXMLRequestDoc(parameterPairs);
- String xmlStr = HTTPRequestor.outputStringFromDoc(inputXMLDoc);
- return xmlStr;
- }
-
- private String generatePairString(NameValuePair[] pairs) {
- StringBuffer pairString = new StringBuffer();
- for (int j = 0; j < pairs.length; j++) {
- if (j > 0) {
- pairString.append("&"); //$NON-NLS-1$
- }
- pairString.append(pairs[j].getName());
- pairString.append("="); //$NON-NLS-1$
- pairString.append(pairs[j].getValue());
- }
- return pairString.toString();
- }
-
- private NameValuePair[] combinePairArrays(NameValuePair[] pairs, NameValuePair[]
bindingPairs) {
- NameValuePair[] allPairs = new NameValuePair[bindingPairs.length +
pairs.length];
- System.arraycopy(bindingPairs, 0, allPairs, 0, bindingPairs.length);
- System.arraycopy(pairs, 0, allPairs, bindingPairs.length, pairs.length);
- return allPairs;
- }
-
- private NameValuePair[] getPairsFromQueryString(String xmlDoc, String
bindingQueryString) {
- NameValuePair[] pairs;
- ParameterParser parser = new ParameterParser();
- List bindingQueryParams = parser.parse(bindingQueryString, '=');
- bindingQueryParams.add(new NameValuePair(null, xmlDoc));
- pairs = (NameValuePair[]) bindingQueryParams.toArray();
- return pairs;
- }
-
- protected NameValuePair[] generatePairs(String pairString) {
- NameValuePair[] pairs;
- int numPairs = 1;
- String dummy = pairString;
- while (dummy.indexOf('&') >= 0) {
- ++numPairs;
- dummy = dummy.substring(dummy.indexOf('&'));
- }
- pairs = new NameValuePair[numPairs];
- // reset dummy in case its been substring'ed
- dummy = pairString;
- int ctr = 0;
- if (numPairs > 1) {
- while (dummy.indexOf('&') >= 0) {
- String name = dummy.substring(0, dummy.indexOf('='));
- String value = dummy.substring(dummy.indexOf('='), dummy
- .indexOf('&'));
- pairs[ctr] = new NameValuePair(name, value);
- ++ctr;
- }
- // last one
- String name = dummy.substring(0, dummy.indexOf('='));
- String value = dummy.substring(dummy.indexOf('='), dummy
- .indexOf('&'));
- pairs[ctr] = new NameValuePair(name, value);
- }
- return pairs;
- }
-
- public Serializable getRequestObject(int i) throws ConnectorException {
- HttpMethod method = request;
- HttpInfo newInfo = new HttpInfo();
- newInfo.m_distinguishingId = i;
- try {
- newInfo.m_uri = method.getURI().getEscapedURI();
- } catch (URIException urie) {
- ConnectorException ce = new ConnectorException(
- com.metamatrix.connector.xml.http.Messages
- .getString("HTTPExecutor.unable.to.recreate.uri"));
//$NON-NLS-1$
- ce.setStackTrace(urie.getStackTrace());
- throw ce;
- }
- if (method instanceof GetMethod) {
- newInfo.m_request = method.getQueryString();
- newInfo.m_method = HTTPConnectorState.GET;
- newInfo.m_paramMethod = null;
- } else {
- newInfo.m_method = HTTPConnectorState.POST;
- NameValuePair[] pairs = ((PostMethod) method).getParameters();
- if (pairs == null) {
- newInfo.m_paramMethod = HttpInfo.RESPONSEBODY;
- if ((newInfo.m_request = ((StringRequestEntity) (((PostMethod) method)
- .getRequestEntity())).getContent()) == null) {
- ConnectorException ce = new ConnectorException(
- com.metamatrix.connector.xml.http.Messages
-
.getString("HTTPExecutor.unable.to.recreate.request")); //$NON-NLS-1$
- throw ce;
- }
- } else {
- newInfo.m_paramMethod = HttpInfo.NAMEVALUE;
- newInfo.m_request = generatePairString(pairs);
- }
- }
- return newInfo;
- }
-
- private void setAllowHttp500(boolean allowHttp500) {
- m_allowHttp500 = allowHttp500;
- }
-
- public boolean getAllowHttp500() {
- return m_allowHttp500;
- }
-
+
@Override
public void closeStreams() {
- releaseDocumentStream();
+ for(HTTPRequest request : requests) {
+ if (request != null) {
+ request.release();
+ request = null;
+ }
+ }
}
-
- private void setExeInfo(ExecutionInfo exeInfo) {
- this.exeInfo = exeInfo;
- }
-
- protected ExecutionInfo getExeInfo() {
- return exeInfo;
- }
- private void setState(HTTPConnectorState state) {
- this.state = state;
+ protected void createRequests(XMLExecution execution, ExecutionInfo exeInfo,
+ List<CriteriaDesc[]> requestPerms) throws ConnectorException {
+ for (CriteriaDesc[] criteria : requestPerms) {
+ List<CriteriaDesc> criteriaList = Arrays.asList(criteria);
+ HTTPRequest request = new HTTPRequest(this.state, execution, exeInfo,
criteriaList);
+ requests.add(request);
+ }
}
-
- protected HTTPConnectorState getState() {
- return state;
- }
-
- protected String buildUriString() {
- String uriString = "<" + buildRawUriString() + ">";
//$NON-NLS-1$
- getLogger().logDetail("XML Connector Framework: using url " + uriString);
//$NON-NLS-1$
- return uriString;
- }
-
- protected ConnectorLogger getLogger() {
- return getState().getLogger();
- }
-
- protected String buildRawUriString() {
- String location = getExeInfo().getLocation();
- if (location != null) {
- // If the location is a URL, it replaces the full URL (first part
- // set in the
- // connector binding and second part set in the model).
- try {
- new URL(location);
- return location;
- } catch (MalformedURLException e) {
- }
- }
-
- if (location == null) {
- final String tableServletCallPathProp = "ServletCallPathforURL";
//$NON-NLS-1$
- location = getExeInfo().getOtherProperties().getProperty(
- tableServletCallPathProp);
- }
-
- String retval = (getState()).getUri();
- if (location != null && location.trim().length() > 0) {
- retval = retval + "/" + location; //$NON-NLS-1$
- }
- return retval;
- }
-
- public InputStream addStreamFilters(InputStream response, ConnectorLogger logger)
- throws ConnectorException {
-
- if(getState().isLogRequestResponse()) {
- response = new LoggingInputStreamFilter(response, logger);
- }
-
- InputStream filter = null;
- try {
- Class pluggableFilter =
Thread.currentThread().getContextClassLoader().loadClass(getState().getPluggableInputStreamFilterClass());
- Constructor ctor = pluggableFilter.getConstructor(
- new Class[] { java.io.InputStream.class,
org.teiid.connector.api.ConnectorLogger.class});
- filter = (InputStream) ctor.newInstance(new Object[] {response, logger});
- } catch (Exception cnf) {
- throw new ConnectorException(cnf);
- }
- return filter;
- }
-
- /**
- * Examines the Query to determine if a request to a source is needed. If any of the
- * request parameters is a ResponseIn, then we don't need to make a request because
it
- * has already been made by another call to Execution.execute()
- */
- public static boolean checkIfRequestIsNeeded(ExecutionInfo info) throws
ConnectorException {
- List cols = info.getRequestedColumns();
- boolean retVal = true;
- Iterator paramIter = cols.iterator();
- while(paramIter.hasNext()) {
- ParameterDescriptor desc = (ParameterDescriptor) paramIter.next();
-
if(desc.getRole().equalsIgnoreCase(ParameterDescriptor.ROLE_COLUMN_PROPERTY_NAME_RESPONSE_IN))
{
- retVal = false;
- break;
- }
- }
- return retVal;
- }
-
- protected String removeAngleBrackets(String uri) {
- char[] result = new char[uri.length()];
- char[] source = uri.toCharArray();
- int r = 0;
- char v;
- for(int i = 0; i < source.length; i++) {
- v = source[i];
- if(v == '<' || v == '>')
- continue;
- result[r] = v;
- ++r;
- }
- return new String(result).trim();
- }
-
- protected void attemptConditionalLog(String message) {
- if (getState().isLogRequestResponse()) {
- getLogger().logInfo(message);
- }
- }
-
- /**
- * Because of the structure of relational databases it is a simple and common practice
- * to return the vaule of a critera in a result set. For instance,
- * SELECT name, ssn from people where ssn='xxx-xx-xxxx'
- * In a Request/Response XML scenario, there is no guarantee that ssn is in the
response.
- * In most cases it will not be. In order to meet the relational users expectation
that
- * the value for a select critera can be returned we stash the value from the parameter
- * in the output value and then fetch it when gathering results if possible. In some
cases
- * this is not possible, and in those cases we throw a ConnectorException.
Implementations
- * of this class can override cannotProjectParameter(CriteriaDesc parmCriteria) to make
the
- * determination.
- */
- private void processOutputXPathDescs(final List requestedColumns, final List
parameterPairs) throws ConnectorException {
- for (int i = 0; i < requestedColumns.size(); i++) {
- OutputXPathDesc xPath = (com.metamatrix.connector.xml.base.OutputXPathDesc)
requestedColumns.get(i);
- if (xPath.isParameter() && xPath.getXPath() == null) {
- setOutputValues(parameterPairs, xPath);
- }
- }
- }
-
- /**
- * Put the input parameter value in the result column value if possible.
- */
- private void setOutputValues(final List parameterPairs, OutputXPathDesc xPath) throws
ConnectorException {
- int colNum = xPath.getColumnNumber();
- for (int x = 0; x < parameterPairs.size(); x++) {
- CriteriaDesc parmCriteria =
- (CriteriaDesc) parameterPairs.get(x);
- if (parmCriteria.getColumnNumber() == colNum) {
- if (cannotProjectParameter(parmCriteria)) {
- throw new
ConnectorException(Messages.getString("HTTPExecutor.cannot.project.repeating.values"));
//$NON-NLS-1$
- } else {
- xPath.setCurrentValue(parmCriteria.getCurrentIndexValue());
- break;
- }
- }
- }
- }
-
-
}
Added:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPRequest.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPRequest.java
(rev 0)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/http/HTTPRequest.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -0,0 +1,584 @@
+package com.metamatrix.connector.xml.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.URIException;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.apache.commons.httpclient.util.ParameterParser;
+import org.jdom.Document;
+import org.teiid.connector.api.ConnectorException;
+import org.teiid.connector.api.ConnectorLogger;
+import org.teiid.connector.api.ExecutionContext;
+
+import com.metamatrix.connector.xml.Constants;
+import com.metamatrix.connector.xml.SAXFilterProvider;
+import com.metamatrix.connector.xml.XMLConnection;
+import com.metamatrix.connector.xml.XMLExecution;
+import com.metamatrix.connector.xml.base.CriteriaDesc;
+import com.metamatrix.connector.xml.base.DocumentBuilder;
+import com.metamatrix.connector.xml.base.ExecutionInfo;
+import com.metamatrix.connector.xml.base.LoggingInputStreamFilter;
+import com.metamatrix.connector.xml.base.OutputXPathDesc;
+import com.metamatrix.connector.xml.base.ParameterDescriptor;
+import com.metamatrix.connector.xml.base.RequestGenerator;
+import com.metamatrix.connector.xml.cache.CachedXMLStream;
+import com.metamatrix.connector.xml.streaming.DocumentImpl;
+
+public class HTTPRequest extends BaseRequest {
+
+ private HTTPRequestor m_requestor;
+
+ private HttpMethod request;
+
+ private boolean m_allowHttp500;
+
+ public static final String PARM_INPUT_XPATH_TABLE_PROPERTY_NAME =
"XPathRootForInput"; //$NON-NLS-1$
+
+ public static final String PARM_INPUT_NAMESPACE_TABLE_PROPERTY_NAME =
"NamespaceForDocument"; //$NON-NLS-1$
+
+
+ public HTTPRequest(HTTPConnectorState state, XMLExecution execution,
+ ExecutionInfo exeInfo, List<CriteriaDesc> parameters) throws ConnectorException
{
+ super(state, execution, exeInfo, parameters);
+ processOutputXPathDescs(exeInfo.getRequestedColumns()
+ , parameters);
+ initialize();
+ createRequests();
+ }
+
+ protected void initialize() throws ConnectorException {
+ m_requestor = new HTTPRequestor(state.getLogger(), state.getAccessMethod());
+ setAllowHttp500(false);
+ try {
+ String uri = buildRawUriString();
+ m_requestor.validateURL(uri);
+ } catch (IOException ioe) {
+ throw new ConnectorException(ioe);
+ }
+ state.getLogger()
+ .logDetail(Messages.getString("HTTPExecutor.url.validated"));
//$NON-NLS-1$
+ }
+
+ public com.metamatrix.connector.xml.Document getDocumentStream() throws
ConnectorException {
+ com.metamatrix.connector.xml.Document document;
+ ExecutionContext exeContext = execution.getExeContext();
+ String cacheKey = getCacheKey();
+
+ // Is this a request part joining across a document
+ CriteriaDesc criterion = this.exeInfo.getResponseIDCriterion();
+ if (null != criterion) {
+ String responseid = (String) (criterion.getValues().get(0));
+
+ if(null == exeContext.get(responseid)) {
+ throw new
ConnectorException(Messages.getString("HTTPExecutor.No.doc.in.cache"));
+ } else {
+ InputStream stream = new CachedXMLStream(exeContext, responseid);
+ document = new DocumentImpl(stream, cacheKey);
+
+ }
+ } else {
+ // Not a join, but might still be cached.
+ if (null == exeContext.get(cacheKey)) {
+ // Not cached, so make the request
+ SAXFilterProvider provider = null;
+ provider = getState().getSAXFilterProvider();
+ InputStream responseBody = executeRequest();
+ InputStream filteredStream = addStreamFilters(responseBody,
getLogger());
+ document = new DocumentImpl(filteredStream, cacheKey);
+ } else {
+ InputStream stream = new CachedXMLStream(exeContext, cacheKey);
+ document = new DocumentImpl(stream, cacheKey);
+ }
+ }
+ return document;
+ }
+
+ /**
+ * Because of the structure of relational databases it is a simple and common practice
+ * to return the vaule of a critera in a result set. For instance,
+ * SELECT name, ssn from people where ssn='xxx-xx-xxxx'
+ * In a Request/Response XML scenario, there is no guarantee that ssn is in the
response.
+ * In most cases it will not be. In order to meet the relational users expectation
that
+ * the value for a select critera can be returned we stash the value from the parameter
+ * in the output value and then fetch it when gathering results if possible. In some
cases
+ * this is not possible, and in those cases we throw a ConnectorException.
Implementations
+ * of this class can override cannotProjectParameter(CriteriaDesc parmCriteria) to make
the
+ * determination.
+ */
+ private void processOutputXPathDescs(final List requestedColumns, final List
parameterPairs) throws ConnectorException {
+ for (int i = 0; i < requestedColumns.size(); i++) {
+ OutputXPathDesc xPath = (com.metamatrix.connector.xml.base.OutputXPathDesc)
requestedColumns.get(i);
+ if (xPath.isParameter() && xPath.getXPath() == null) {
+ setOutputValues(parameterPairs, xPath);
+ }
+ }
+ }
+
+ private void setAllowHttp500(boolean allowHttp500) {
+ m_allowHttp500 = allowHttp500;
+ }
+
+ public boolean getAllowHttp500() {
+ return m_allowHttp500;
+ }
+
+
+
+ public void release() {
+ request.releaseConnection();
+ }
+
+ protected String getCacheKey() throws ConnectorException {
+
+ if (request == null) {
+ String message = com.metamatrix.connector.xml.http.Messages
+ .getString("HttpExecutor.cannot.create.cachekey");
+ throw new ConnectorException(message);
+ }
+ // the key consists of a String in the form of
+ // |uri|parameterList|
+ String userName = execution.getConnection().getUser();
+ String session = execution.getConnection().getQueryId();
+
+ StringBuffer cacheKey = new StringBuffer();
+ cacheKey.append("|"); //$NON-NLS-1$
+ cacheKey.append(userName);
+ cacheKey.append("|");
+ cacheKey.append(session);
+ cacheKey.append("|");
+ cacheKey.append(getUriString());
+ cacheKey.append("|"); //$NON-NLS-1$
+
+ if (request instanceof PostMethod) {
+ NameValuePair[] pairs = ((PostMethod) request).getParameters();
+ if (pairs == null || pairs.length == 0) {
+ if (((PostMethod) request).getRequestEntity() != null) {
+ String requestBodyAsString = ((StringRequestEntity) (((PostMethod)
request)
+ .getRequestEntity())).getContent();
+ cacheKey.append(requestBodyAsString);
+ }
+ } else {
+ cacheKey.append(generatePairString(pairs));
+ }
+ } else {
+ cacheKey.append(request.getQueryString());
+ }
+ return cacheKey.toString();
+ }
+
+ protected InputStream executeRequest() throws ConnectorException {
+ HttpClient client = (getState()).getClient();
+ XMLConnection conn = execution.getConnection();
+ try {
+ HTTPTrustDeserializer ser = (HTTPTrustDeserializer) conn
+ .getTrustedPayloadHandler();
+ ser.modifyRequest(client, request);
+ } catch (ClassCastException cce) {
+ throw new ConnectorException(
+ com.metamatrix.connector.xml.http.Messages
+
.getString("HTTPExecutor.class.not.instance.of.HTTPTrustDeserializer"));
+ } catch (Exception e) {
+ ConnectorException ce = new ConnectorException(
+ com.metamatrix.connector.xml.http.Messages
+
.getString("HTTPExecutor.unable.to.create.trust.deserializer"));
+ ce.setStackTrace(e.getStackTrace());
+ throw ce;
+ }
+ modifyRequest(client, request);
+ InputStream responseBody = m_requestor.fetchXMLDocument(client,
+ request, getAllowHttp500());
+ return responseBody;
+ }
+
+
+ private void createRequests() throws ConnectorException {
+ if (checkIfRequestIsNeeded(exeInfo)) {
+ setRequests(this.parameters, getUriString());
+ }
+ }
+
+ protected void modifyRequest(HttpClient client, HttpMethod method)
+ throws ConnectorException {
+ // to be overridden by subclasses
+ }
+
+ public boolean cannotProjectParameter(CriteriaDesc parmCriteria) {
+ return parmCriteria.getNumberOfValues() > 1
+ && parmCriteria.isUnlimited()
+ && !((getState()).getParameterMethod() ==
HTTPConnectorState.PARAMETER_NAME_VALUE);
+ }
+
+ // this routine builds the input XML document using JDOM structures
+ protected Document buildInputXMLDocument(List parameters,
+ String inputParmsXPath) throws ConnectorException {
+ String namespacePrefixes = exeInfo.getOtherProperties()
+ .getProperty(Constants.NAMESPACE_PREFIX_PROPERTY_NAME);
+ DocumentBuilder builder = new DocumentBuilder();
+ return builder.buildDocument(parameters, inputParmsXPath,
+ namespacePrefixes);
+ }
+
+ protected NameValuePair[] createNameValuePairs(List paramPairs)
+ throws ConnectorException {
+ NameValuePair[] pairs = new NameValuePair[paramPairs.size()];
+ for (int i = 0; i < pairs.length; i++) {
+ CriteriaDesc cd = (CriteriaDesc) paramPairs.get(i);
+ String name = (cd.getInputXpath() == null || cd.getInputXpath()
+ .length() == 0) ? cd.getColumnName() : cd.getInputXpath();
+ NameValuePair pair = new NameValuePair(name, cd
+ .getCurrentIndexValue());
+ pairs[i] = pair;
+ }
+
+ return pairs;
+ }
+
+ protected void setRequests(List<CriteriaDesc> params, String bindingURIValue)
+ throws ConnectorException {
+
+ String xmlDoc = null;
+ // see if there are parameters to set
+ if (getState().getParameterMethod() == HTTPConnectorState.PARAMETER_NONE
+ || params.size() == 0) {
+ getLogger()
+ .logTrace("XML Connector Framework: no parameters for
request"); //$NON-NLS-1$
+ }
+ List<CriteriaDesc[]> requestPerms = RequestGenerator.getRequests(params);
+
+ for (CriteriaDesc[] queryParameters: requestPerms) {
+ NameValuePair[] pairs = null;
+ String bindingURI = null;
+ String bindingQueryString = null;
+ if(-1 != bindingURIValue.indexOf('?')) {
+ bindingURI = bindingURIValue.substring(1,
bindingURIValue.indexOf('?'));
+ bindingQueryString =
bindingURIValue.substring(bindingURIValue.indexOf('?') + 1,
bindingURIValue.length() -1);
+ } else {
+ bindingURI = bindingURIValue;
+ }
+
+ if(-1 != bindingURI.indexOf("<") || -1 !=
bindingURI.indexOf("<")) {
+ bindingURI = removeAngleBrackets(bindingURI);
+ }
+
+ java.util.List newList = java.util.Arrays.asList(queryParameters);
+ List queryList = new ArrayList(newList);
+
+ String parameterMethod = getState().getParameterMethod();
+ if (parameterMethod == HTTPConnectorState.PARAMETER_XML_REQUEST ||
+ parameterMethod == HTTPConnectorState.PARAMETER_XML_QUERY_STRING ) {
+ xmlDoc = createXMLRequestDocString(queryList);
+ String paramName = getState().getXmlParameterName();
+ if(null != paramName) {
+ pairs = new NameValuePair[] { new NameValuePair(getState()
+ .getXmlParameterName(), xmlDoc) };
+ if (pairs != null) {
+ attemptConditionalLog("XML Connector Framework: request
parameters -\n "
+ + generatePairString(pairs));
+ }
+ }
+ } else if (parameterMethod == HTTPConnectorState.PARAMETER_NAME_VALUE ||
+ parameterMethod == HTTPConnectorState.PARAMETER_NONE) {
+ pairs = createNameValuePairs(queryList);
+ }
+
+ HttpMethod method = null;
+ String accessMethod = getState().getAccessMethod();
+ if(accessMethod.equals(HTTPConnectorState.POST)) {
+ method = m_requestor.generateMethod(bindingURI);
+ PostMethod post = (PostMethod) method;
+ if (pairs == null) {
+ //POST-DOC-NO_PARAM_NAME
+ if(bindingQueryString != null) {
+ pairs = getPairsFromQueryString(xmlDoc, bindingQueryString);
+ post.addParameters(pairs);
+ attemptConditionalLog("XML Connector Framework: request
parameters -\n " + generatePairString(pairs)); //$NON-NLS-1$
+ } else {
+ post.setRequestEntity(new StringRequestEntity(xmlDoc));
+ attemptConditionalLog("XML Connector Framework: request body
set to: " + xmlDoc); //$NON-NLS-1$
+ }
+ } else {
+ //POST-DOC-WITH_PARAM_NAME
+ if(parameterMethod == HTTPConnectorState.PARAMETER_XML_QUERY_STRING)
{
+ //QUERY_STRING
+ StringBuffer requestEntity = new StringBuffer();
+ if(null != bindingQueryString) {
+ requestEntity.append(bindingQueryString);
+ requestEntity.append('&');
+ }
+ requestEntity.append(getState().getXmlParameterName());
+ requestEntity.append('=');
+ requestEntity.append(xmlDoc);
+ URI realURI = null;
+ try {
+ realURI = new URI(bindingURI + "?" +
URLEncoder.encode(requestEntity.toString()));
+ String fullQueryString = realURI.toString();
+ method = m_requestor.generateMethod(fullQueryString);
+ attemptConditionalLog("XML Connector Framework: request
set to -\n " + fullQueryString); //$NON-NLS-1$
+ } catch (URISyntaxException e) {
+ throw new ConnectorException(e.getMessage());
+ }
+ } else {
+ //XML_REQUEST
+ if(null != bindingQueryString){
+ NameValuePair[] bindingPairs =
getPairsFromQueryString(xmlDoc, bindingQueryString);
+ pairs = combinePairArrays(pairs, bindingPairs);
+ }
+ post.addParameters(pairs);
+ attemptConditionalLog("XML Connector Framework: request
parameters -\n " + generatePairString(pairs)); //$NON-NLS-1$
+ }
+ }
+ } else if (accessMethod.equals(HTTPConnectorState.GET)){
+ method = m_requestor.generateMethod(bindingURI);
+ if (pairs == null) {
+ throw new ConnectorException(
+ com.metamatrix.connector.xml.http.Messages
+
.getString("HTTPExecutor.parameter.name.required.for.get")); //$NON-NLS-1$
+ }
+ if(null != bindingQueryString){
+ NameValuePair[] bindingPairs = getPairsFromQueryString(xmlDoc,
bindingQueryString);
+ pairs = combinePairArrays(pairs, bindingPairs);
+ }
+ addGetValues(pairs, method);
+ attemptConditionalLog("XML Connector Framework: request paramters
-\n " + generatePairString(pairs)); //$NON-NLS-1$
+
+ }
+ request = method;
+ getLogger().logInfo("XML Connector Framework: request created");
//$NON-NLS-1$
+ }
+ }
+
+ protected void addGetValues(NameValuePair[] pairs, HttpMethod method)
+ throws ConnectorException {
+ method.setQueryString(pairs);
+ }
+
+ protected void addPostValues(NameValuePair[] pairs, PostMethod method)
+ throws ConnectorException {
+ method.addParameters(pairs);
+ }
+
+ protected Document createXMLRequestDoc(List parameterPairs)
+ throws ConnectorException {
+ Properties props = exeInfo.getOtherProperties();
+ String inputParmsXPath = props
+ .getProperty(PARM_INPUT_XPATH_TABLE_PROPERTY_NAME);
+ Document inputXMLDoc = buildInputXMLDocument(parameterPairs,
+ inputParmsXPath);
+ return inputXMLDoc;
+ }
+
+ protected String createXMLRequestDocString(List parameterPairs)
+ throws ConnectorException {
+ Document inputXMLDoc = createXMLRequestDoc(parameterPairs);
+ String xmlStr = HTTPRequestor.outputStringFromDoc(inputXMLDoc);
+ return xmlStr;
+ }
+
+ private String generatePairString(NameValuePair[] pairs) {
+ StringBuffer pairString = new StringBuffer();
+ for (int j = 0; j < pairs.length; j++) {
+ if (j > 0) {
+ pairString.append("&"); //$NON-NLS-1$
+ }
+ pairString.append(pairs[j].getName());
+ pairString.append("="); //$NON-NLS-1$
+ pairString.append(pairs[j].getValue());
+ }
+ return pairString.toString();
+ }
+
+ private NameValuePair[] combinePairArrays(NameValuePair[] pairs, NameValuePair[]
bindingPairs) {
+ NameValuePair[] allPairs = new NameValuePair[bindingPairs.length +
pairs.length];
+ System.arraycopy(bindingPairs, 0, allPairs, 0, bindingPairs.length);
+ System.arraycopy(pairs, 0, allPairs, bindingPairs.length, pairs.length);
+ return allPairs;
+ }
+
+ private NameValuePair[] getPairsFromQueryString(String xmlDoc, String
bindingQueryString) {
+ NameValuePair[] pairs;
+ ParameterParser parser = new ParameterParser();
+ List bindingQueryParams = parser.parse(bindingQueryString, '=');
+ bindingQueryParams.add(new NameValuePair(null, xmlDoc));
+ pairs = (NameValuePair[]) bindingQueryParams.toArray();
+ return pairs;
+ }
+
+ protected NameValuePair[] generatePairs(String pairString) {
+ NameValuePair[] pairs;
+ int numPairs = 1;
+ String dummy = pairString;
+ while (dummy.indexOf('&') >= 0) {
+ ++numPairs;
+ dummy = dummy.substring(dummy.indexOf('&'));
+ }
+ pairs = new NameValuePair[numPairs];
+ // reset dummy in case its been substring'ed
+ dummy = pairString;
+ int ctr = 0;
+ if (numPairs > 1) {
+ while (dummy.indexOf('&') >= 0) {
+ String name = dummy.substring(0, dummy.indexOf('='));
+ String value = dummy.substring(dummy.indexOf('='), dummy
+ .indexOf('&'));
+ pairs[ctr] = new NameValuePair(name, value);
+ ++ctr;
+ }
+ // last one
+ String name = dummy.substring(0, dummy.indexOf('='));
+ String value = dummy.substring(dummy.indexOf('='), dummy
+ .indexOf('&'));
+ pairs[ctr] = new NameValuePair(name, value);
+ }
+ return pairs;
+ }
+
+ public Serializable getRequestObject(int i) throws ConnectorException {
+ HttpMethod method = request;
+ HttpInfo newInfo = new HttpInfo();
+ newInfo.m_distinguishingId = i;
+ try {
+ newInfo.m_uri = method.getURI().getEscapedURI();
+ } catch (URIException urie) {
+ ConnectorException ce = new ConnectorException(
+ com.metamatrix.connector.xml.http.Messages
+ .getString("HTTPExecutor.unable.to.recreate.uri"));
//$NON-NLS-1$
+ ce.setStackTrace(urie.getStackTrace());
+ throw ce;
+ }
+ if (method instanceof GetMethod) {
+ newInfo.m_request = method.getQueryString();
+ newInfo.m_method = HTTPConnectorState.GET;
+ newInfo.m_paramMethod = null;
+ } else {
+ newInfo.m_method = HTTPConnectorState.POST;
+ NameValuePair[] pairs = ((PostMethod) method).getParameters();
+ if (pairs == null) {
+ newInfo.m_paramMethod = HttpInfo.RESPONSEBODY;
+ if ((newInfo.m_request = ((StringRequestEntity) (((PostMethod) method)
+ .getRequestEntity())).getContent()) == null) {
+ ConnectorException ce = new ConnectorException(
+ com.metamatrix.connector.xml.http.Messages
+
.getString("HTTPExecutor.unable.to.recreate.request")); //$NON-NLS-1$
+ throw ce;
+ }
+ } else {
+ newInfo.m_paramMethod = HttpInfo.NAMEVALUE;
+ newInfo.m_request = generatePairString(pairs);
+ }
+ }
+ return newInfo;
+ }
+
+
+ private void setState(HTTPConnectorState state) {
+ this.state = state;
+ }
+
+ protected HTTPConnectorState getState() {
+ return state;
+ }
+
+ protected ConnectorLogger getLogger() {
+ return getState().getLogger();
+ }
+
+
+ public InputStream addStreamFilters(InputStream response, ConnectorLogger logger)
+ throws ConnectorException {
+
+ if(getState().isLogRequestResponse()) {
+ response = new LoggingInputStreamFilter(response, logger);
+ }
+
+ InputStream filter = null;
+ try {
+ Class pluggableFilter =
Thread.currentThread().getContextClassLoader().loadClass(getState().getPluggableInputStreamFilterClass());
+ Constructor ctor = pluggableFilter.getConstructor(
+ new Class[] { java.io.InputStream.class,
org.teiid.connector.api.ConnectorLogger.class});
+ filter = (InputStream) ctor.newInstance(new Object[] {response, logger});
+ } catch (Exception cnf) {
+ throw new ConnectorException(cnf);
+ }
+ return filter;
+ }
+
+ /**
+ * Examines the Query to determine if a request to a source is needed. If any of the
+ * request parameters is a ResponseIn, then we don't need to make a request because
it
+ * has already been made by another call to Execution.execute()
+ */
+ public static boolean checkIfRequestIsNeeded(ExecutionInfo info) throws
ConnectorException {
+ List cols = info.getRequestedColumns();
+ boolean retVal = true;
+ Iterator paramIter = cols.iterator();
+ while(paramIter.hasNext()) {
+ ParameterDescriptor desc = (ParameterDescriptor) paramIter.next();
+
if(desc.getRole().equalsIgnoreCase(ParameterDescriptor.ROLE_COLUMN_PROPERTY_NAME_RESPONSE_IN))
{
+ retVal = false;
+ break;
+ }
+ }
+ return retVal;
+ }
+
+ protected String removeAngleBrackets(String uri) {
+ char[] result = new char[uri.length()];
+ char[] source = uri.toCharArray();
+ int r = 0;
+ char v;
+ for(int i = 0; i < source.length; i++) {
+ v = source[i];
+ if(v == '<' || v == '>')
+ continue;
+ result[r] = v;
+ ++r;
+ }
+ return new String(result).trim();
+ }
+
+ protected void attemptConditionalLog(String message) {
+ if (getState().isLogRequestResponse()) {
+ getLogger().logInfo(message);
+ }
+ }
+
+
+ /**
+ * Put the input parameter value in the result column value if possible.
+ */
+ private void setOutputValues(final List parameterPairs, OutputXPathDesc xPath) throws
ConnectorException {
+ int colNum = xPath.getColumnNumber();
+ for (int x = 0; x < parameterPairs.size(); x++) {
+ CriteriaDesc parmCriteria =
+ (CriteriaDesc) parameterPairs.get(x);
+ if (parmCriteria.getColumnNumber() == colNum) {
+ if (cannotProjectParameter(parmCriteria)) {
+ throw new
ConnectorException(Messages.getString("HTTPExecutor.cannot.project.repeating.values"));
//$NON-NLS-1$
+ } else {
+ xPath.setCurrentValue(parmCriteria.getCurrentIndexValue());
+ break;
+ }
+ }
+ }
+ }
+
+
+
+
+
+}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPExecution.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPExecution.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPExecution.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -22,6 +22,6 @@
@Override
public ResultProducer getStreamProducer() throws ConnectorException {
return new SOAPExecutor((SOAPConnectorState) connection.getState(),
- this, exeInfo);
+ this, exeInfo, analyzer);
}
}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPExecutor.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPExecutor.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPExecutor.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -24,134 +24,34 @@
package com.metamatrix.connector.xml.soap;
-import java.io.InputStream;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.Arrays;
import java.util.List;
-import javax.xml.namespace.QName;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.ws.Dispatch;
-import javax.xml.ws.Service;
-import javax.xml.ws.soap.SOAPBinding;
-
-import org.jdom.Document;
-import org.jdom.output.XMLOutputter;
-import org.teiid.connector.api.ConnectorEnvironment;
import org.teiid.connector.api.ConnectorException;
-import com.metamatrix.connector.xml.Constants;
import com.metamatrix.connector.xml.SOAPConnectorState;
-import com.metamatrix.connector.xml.TrustedPayloadHandler;
-import com.metamatrix.connector.xml.XMLConnectorState;
import com.metamatrix.connector.xml.XMLExecution;
import com.metamatrix.connector.xml.base.CriteriaDesc;
-import com.metamatrix.connector.xml.base.DocumentBuilder;
import com.metamatrix.connector.xml.base.ExecutionInfo;
-import com.metamatrix.connector.xml.base.RequestGenerator;
-import com.metamatrix.connector.xml.cache.CachingOutputStream;
+import com.metamatrix.connector.xml.base.QueryAnalyzer;
+import com.metamatrix.connector.xml.http.HTTPConnectorState;
import com.metamatrix.connector.xml.http.HTTPExecutor;
-import com.metamatrix.connector.xmlsource.soap.SecurityToken;
public class SOAPExecutor extends HTTPExecutor {
- SecurityToken secToken;
- XMLOutputter xmlOutputter = new XMLOutputter();
- Document doc;
-
- public SOAPExecutor(SOAPConnectorState state, XMLExecution execution, ExecutionInfo
exeInfo) throws ConnectorException {
- super((XMLConnectorState)state, execution, exeInfo);
+ public SOAPExecutor(SOAPConnectorState state, XMLExecution execution, ExecutionInfo
exeInfo, QueryAnalyzer analyzer) throws ConnectorException {
+ super((HTTPConnectorState) state, execution, exeInfo, analyzer);
}
-
- protected InputStream getDocumentStream() throws ConnectorException {
- try {
- TrustedPayloadHandler handler = execution.getConnection().getTrustedPayloadHandler();
- ConnectorEnvironment env = execution.getConnection().getConnectorEnv();
- secToken = SecurityToken.getSecurityToken(env, handler);
-
- QName svcQname = new QName("http://org.apache.cxf",
"foo");
- QName portQName = new QName("http://org.apache.cxf",
"bar");
- Service svc = Service.create(svcQname);
- svc.addPort(
- portQName,
- SOAPBinding.SOAP11HTTP_BINDING,
- removeAngleBrackets(buildUriString()));
-
- Dispatch<Source> dispatch = svc.createDispatch(
- portQName,
- Source.class,
- Service.Mode.PAYLOAD);
-
- String requestDocument = xmlOutputter.outputString(doc);
- attemptConditionalLog(requestDocument);
- StringReader reader = new StringReader(requestDocument);
- Source input = new StreamSource(reader);
- // Invoke the operation.
- Source output = dispatch.invoke(input);
-
- // Process the response.
- CachingOutputStream out = new CachingOutputStream(execution.getExeContext(),
getCacheKey());
- StreamResult result = new StreamResult(out);
- Transformer trans = TransformerFactory.newInstance().newTransformer();
- trans.transform(output, result);
- return out.getCachedXMLStream();
- } catch (Exception e) {
- throw new ConnectorException(e);
- }
- }
-
- protected void setRequests(List params, String uriString)
+
+ @Override
+ protected void createRequests(XMLExecution execution,
+ ExecutionInfo exeInfo, List<CriteriaDesc[]> requestPerms)
throws ConnectorException {
-
- SOAPConnectorState state = (SOAPConnectorState) getState();
- ArrayList requestPerms = RequestGenerator.getRequestPerms(params);
- CriteriaDesc[] queryParameters = (CriteriaDesc[]) requestPerms.get(0);
-
- java.util.List newList = java.util.Arrays.asList(queryParameters);
- ArrayList queryList = new ArrayList(newList);
-
- ArrayList headerParams = new ArrayList();
- ArrayList bodyParams = new ArrayList();
- sortParams(queryList, headerParams, bodyParams);
-
- String namespacePrefixes =
getExeInfo().getOtherProperties().getProperty(Constants.NAMESPACE_PREFIX_PROPERTY_NAME);
- String inputParmsXPath =
getExeInfo().getOtherProperties().getProperty(DocumentBuilder.PARM_INPUT_XPATH_TABLE_PROPERTY_NAME);
- SOAPDocBuilder builder = new SOAPDocBuilder();
- doc = builder.createXMLRequestDoc(bodyParams, (SOAPConnectorState)getState(),
namespacePrefixes, inputParmsXPath);
+ int requestNumber = 0;
+ for (CriteriaDesc[] criteria : requestPerms) {
+ List<CriteriaDesc> criteriaList = Arrays.asList(criteria);
+ SOAPRequest request = new SOAPRequest((SOAPConnectorState) state, execution,
exeInfo, criteriaList, requestNumber ++);
+ requests.add(request);
+ }
}
-
- protected String getCacheKey() throws ConnectorException {
- StringBuffer cacheKey = new StringBuffer();
- cacheKey.append("|"); //$NON-NLS-1$
- cacheKey.append(execution.getConnection().getUser());
- cacheKey.append("|");
- cacheKey.append(execution.getConnection().getQueryId());
- cacheKey.append("|");
- cacheKey.append(buildUriString());
- //cacheKey.append("|"); //$NON-NLS-1$
- //cacheKey.append(xmlOutputter.outputString(doc));
- return cacheKey.toString();
- }
-
- public int getDocumentCount() throws ConnectorException {
- return 1;
- }
- private void sortParams(List allParams, List headerParams, List bodyParams) throws
ConnectorException {
- // sort the parameter list into header and body content
- //replace this later with model extensions
- Iterator paramIter = allParams.iterator();
- while(paramIter.hasNext()) {
- CriteriaDesc desc = (CriteriaDesc) paramIter.next();
- if(desc.getInputXpath().startsWith(SOAPDocBuilder.soapNSLabel + ":" +
SOAPDocBuilder.soapHeader)) { //$NON-NLS-1$
- headerParams.add(desc);
- } else {
- bodyParams.add(desc);
- }
- }
- }
}
Added:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPRequest.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPRequest.java
(rev 0)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/soap/SOAPRequest.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -0,0 +1,143 @@
+package com.metamatrix.connector.xml.soap;
+
+import java.io.InputStream;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.Dispatch;
+import javax.xml.ws.Service;
+import javax.xml.ws.soap.SOAPBinding;
+
+import org.jdom.Document;
+import org.jdom.output.XMLOutputter;
+import org.teiid.connector.api.ConnectorEnvironment;
+import org.teiid.connector.api.ConnectorException;
+
+import com.metamatrix.connector.xml.Constants;
+import com.metamatrix.connector.xml.SOAPConnectorState;
+import com.metamatrix.connector.xml.TrustedPayloadHandler;
+import com.metamatrix.connector.xml.XMLExecution;
+import com.metamatrix.connector.xml.base.CriteriaDesc;
+import com.metamatrix.connector.xml.base.DocumentBuilder;
+import com.metamatrix.connector.xml.base.ExecutionInfo;
+import com.metamatrix.connector.xml.base.RequestGenerator;
+import com.metamatrix.connector.xml.cache.CachingOutputStream;
+import com.metamatrix.connector.xml.http.HTTPConnectorState;
+import com.metamatrix.connector.xmlsource.soap.SecurityToken;
+
+public class SOAPRequest extends com.metamatrix.connector.xml.http.HTTPRequest {
+
+ SecurityToken secToken;
+ XMLOutputter xmlOutputter = new XMLOutputter();
+ Document doc;
+ private int requestNumber;
+
+ public SOAPRequest(SOAPConnectorState connectorState, XMLExecution execution,
+ ExecutionInfo exeInfo, List<CriteriaDesc> parameters, int requestNumber)
+ throws ConnectorException {
+ super((HTTPConnectorState) connectorState, execution, exeInfo, parameters);
+ this.requestNumber = requestNumber;
+ initialize();
+ }
+
+ protected void initialize() {
+ }
+
+ public void release() {
+ }
+
+ protected InputStream executeRequest() throws ConnectorException {
+ try {
+ TrustedPayloadHandler handler = execution.getConnection().getTrustedPayloadHandler();
+ ConnectorEnvironment env = execution.getConnection().getConnectorEnv();
+ secToken = SecurityToken.getSecurityToken(env, handler);
+
+ QName svcQname = new QName("http://org.apache.cxf",
"foo");
+ QName portQName = new QName("http://org.apache.cxf",
"bar");
+ Service svc = Service.create(svcQname);
+ svc.addPort(
+ portQName,
+ SOAPBinding.SOAP11HTTP_BINDING,
+ removeAngleBrackets(getUriString()));
+
+ Dispatch<Source> dispatch = svc.createDispatch(
+ portQName,
+ Source.class,
+ Service.Mode.PAYLOAD);
+
+ String requestDocument = xmlOutputter.outputString(doc);
+ attemptConditionalLog(requestDocument);
+ StringReader reader = new StringReader(requestDocument);
+ Source input = new StreamSource(reader);
+ // Invoke the operation.
+ Source output = dispatch.invoke(input);
+
+ // Process the response.
+ CachingOutputStream out = new CachingOutputStream(execution.getExeContext(),
getCacheKey());
+ StreamResult result = new StreamResult(out);
+ Transformer trans = TransformerFactory.newInstance().newTransformer();
+ trans.transform(output, result);
+ return out.getCachedXMLStream();
+ } catch (Exception e) {
+ throw new ConnectorException(e);
+ }
+ }
+
+ protected void setRequests(List<CriteriaDesc> params, String uriString)
+ throws ConnectorException {
+
+ List<CriteriaDesc[]> requestPerms = RequestGenerator.getRequests(params);
+ CriteriaDesc[] queryParameters = requestPerms.get(0);
+
+ List<CriteriaDesc> newList = java.util.Arrays.asList(queryParameters);
+ List<CriteriaDesc> queryList = new ArrayList<CriteriaDesc>(newList);
+
+ List<CriteriaDesc> headerParams = new ArrayList<CriteriaDesc>();
+ List<CriteriaDesc> bodyParams = new ArrayList<CriteriaDesc>();
+ sortParams(queryList, headerParams, bodyParams);
+
+ String namespacePrefixes =
exeInfo.getOtherProperties().getProperty(Constants.NAMESPACE_PREFIX_PROPERTY_NAME);
+ String inputParmsXPath =
exeInfo.getOtherProperties().getProperty(DocumentBuilder.PARM_INPUT_XPATH_TABLE_PROPERTY_NAME);
+ SOAPDocBuilder builder = new SOAPDocBuilder();
+ doc = builder.createXMLRequestDoc(bodyParams, (SOAPConnectorState)state,
namespacePrefixes, inputParmsXPath);
+ }
+
+ protected String getCacheKey() throws ConnectorException {
+ StringBuffer cacheKey = new StringBuffer();
+ cacheKey.append("|"); //$NON-NLS-1$
+ cacheKey.append(execution.getConnection().getUser());
+ cacheKey.append("|");
+ cacheKey.append(execution.getConnection().getQueryId());
+ cacheKey.append("|");
+ cacheKey.append(getUriString());
+ cacheKey.append(requestNumber);
+ return cacheKey.toString();
+ }
+
+ public int getDocumentCount() throws ConnectorException {
+ return 1;
+ }
+
+ private void sortParams(List<CriteriaDesc> allParams,
+ List<CriteriaDesc> headerParams, List<CriteriaDesc> bodyParams)
+ throws ConnectorException {
+ // sort the parameter list into header and body content
+ // replace this later with model extensions
+ for (CriteriaDesc desc : allParams)
+ if (desc.getInputXpath().startsWith(
+ SOAPDocBuilder.soapNSLabel
+ + ":" + SOAPDocBuilder.soapHeader)) { //$NON-NLS-1$
+ headerParams.add(desc);
+ } else {
+ bodyParams.add(desc);
+ }
+ }
+
+}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/BaseStreamingExecution.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/BaseStreamingExecution.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/BaseStreamingExecution.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -1,6 +1,5 @@
package com.metamatrix.connector.xml.streaming;
-import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
@@ -24,12 +23,19 @@
public abstract class BaseStreamingExecution implements XMLExecution {
protected List<String> xpaths;
+
protected StreamingResultsProducer rowProducer;
+
protected List<Object[]> results;
private int resultIndex;
private Iterator<Document> streamIter;
+
+ // A single query can result in multiple requests to an XML source.
+ // Each request is abstracted by a result producer.
+ // TODO: Do I really need more than one of theses?
protected List<ResultProducer> resultProducers;
private Iterator<ResultProducer> producerIter;
+
protected ExecutionInfo exeInfo;
protected IQuery query;
protected RuntimeMetadata metadata;
@@ -72,8 +78,7 @@
result = Arrays.asList(results.get(resultIndex));
++resultIndex;
} else {
- List rows;
- File xmlFile;
+ List<Object[]> rows;
Document xml;
if(null == streamIter) {
if(null == producerIter) {
@@ -90,7 +95,7 @@
if (rows.isEmpty()) {
continue;
}
- results = rows;
+ results.addAll(rows);
resultIndex = 0;
}
if(resultIndex < results.size()) {
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/ElementProcessor.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/ElementProcessor.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/ElementProcessor.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -15,14 +15,18 @@
import org.teiid.connector.api.ConnectorException;
import com.metamatrix.connector.xml.Document;
+import com.metamatrix.connector.xml.base.CriteriaDesc;
import com.metamatrix.connector.xml.base.ExecutionInfo;
import com.metamatrix.connector.xml.base.OutputXPathDesc;
import com.metamatrix.connector.xml.http.Messages;
/**
- * The ElementProcessor extracts data from a Node based upon paths defined in
- * an ExecutionInfo (aka columns in a query request). The processor is also
- * responsible putting the cacheKey in the response row.
+ * The ElementProcessor extracts data from a Node based upon XPaths defined in
+ * an ExecutionInfo (aka columns in a query request) ro build a single result row.
+ * In this context Node is equivalent to a table in the model.
+ *
+ * The processor is also responsible putting the cacheKey in the response row,
+ * inserting projected parameters, and applying = criteria.
*
*/
public class ElementProcessor {
@@ -32,25 +36,31 @@
private Map<String, OutputXPathDesc> resultPaths;
private OutputXPathDesc cacheKeyColumn;
private Map<String, String> namespacesToPrefixMap;
+ private boolean rowExcluded = false;
public ElementProcessor(ExecutionInfo info) throws ConnectorException {
this.info = info;
- resultPaths = generateXPaths();
+ resultPaths = generateXPaths(info.getRequestedColumns());
namespacesToPrefixMap = info.getNamespaceToPrefixMap();
}
/**
* Iterate down the element getting column data from the matching paths.
- * @param element
- * @param xml
+ * @param element the Node representing the Table in the model.
* @return a single result row
*/
public Object[] process(Node element) {
+ setRowExcluded(false);
row = new Object[resultPaths.size()];
listChildren(element, "");
return row;
}
+ /**
+ * Iterate over the result and insert the ResponseId in the correct column
+ * @param xml the XML Document
+ * @param result the result batch for the query
+ */
public void insertResponseId(Document xml, List<Object[]> result) {
if (null != cacheKeyColumn) {
Object[] aRow;
@@ -89,8 +99,11 @@
Attribute attribute = temp.getAttribute(i);
String attrPath = path + "/@" + getLocalQName(attribute);
if(resultPaths.containsKey(attrPath)) {
- getColumn(attribute, attrPath);
- }
+ handleNode(attribute, attrPath);
+ if(isRowExcluded()) {
+ return;
+ }
+ }
}
}
else if (current instanceof ProcessingInstruction) {
@@ -101,14 +114,20 @@
DocType temp = (DocType) current;
path = path + '/' + temp.getRootElementName();
}
- else if (current instanceof Text /*|| current instanceof Comment*/) {
+ else if (current instanceof Text) {
String textPath = path + "/text()";
if(resultPaths.containsKey(textPath)) {
- getColumn(current, textPath);
+ handleNode(current, textPath);
+ if(isRowExcluded()) {
+ return;
+ }
}
}
for (int i = 0; i < current.getChildCount(); i++) {
+ if(isRowExcluded()) {
+ return;
+ }
Node next = current.getChild(i);
String childPath = path;
if (next instanceof Element) {
@@ -154,19 +173,56 @@
return result;
}
- private void getColumn(Node node, String path) {
- OutputXPathDesc columnMetadata = resultPaths.get(path);
- int columnNum = columnMetadata.getColumnNumber();
- //TODO: type conversion
- row[columnNum] = node.getValue();
-
+ private void handleNode(Node node, String parentPath) {
+ OutputXPathDesc columnMetadata = resultPaths.get(parentPath);
+ int columnNum = columnMetadata.getColumnNumber();
+
+ if(!passesCriteriaCheck(info.getCriteria(), node.getValue(), columnNum)) {
+ setRowExcluded(true);
+ return;
+ } else {
+ //TODO: type conversion
+ row[columnNum] = node.getValue();
+ }
}
+
+ /**
+ * Tests the value against the criteria to determine if the value should be
+ * included in the result set.
+ *
+ * @param criteriaPairs
+ * @param value
+ * @param colNum
+ * @return
+ * @throws ConnectorException
+ */
+ private static boolean passesCriteriaCheck(List<CriteriaDesc> criteriaPairs,
+ String value, int colNum) {
+ // Need to test this code
+ for (CriteriaDesc criteria: criteriaPairs) {
+ if (colNum == criteria.getColumnNumber()) {
+ return evaluate(value, criteria);
+ }
+ }
+ return true;
+ }
+
+ public static boolean evaluate(String currentValue,
+ CriteriaDesc criteria) {
+ // this is the criteriaq for the col
+ List values = criteria.getValues();
+ for (Object criterion: values) {
+ if (criterion.equals(currentValue)) {
+ return true;
+ }
+ }
+ return false; // no matching value
- private Map<String, OutputXPathDesc> generateXPaths() throws ConnectorException {
+ }
+
+ private Map<String, OutputXPathDesc> generateXPaths(List<OutputXPathDesc>
columns) throws ConnectorException {
Map<String, OutputXPathDesc> xpaths = new HashMap<String,
OutputXPathDesc>();
- OutputXPathDesc xPathDesc = null;
- for (Iterator<OutputXPathDesc> iter = info.getRequestedColumns().iterator();
iter.hasNext(); ) {
- xPathDesc = iter.next();
+ for (OutputXPathDesc xPathDesc: columns) {
String xpathString = null;
if (!xPathDesc.isResponseId()) {
xpathString = xPathDesc.getXPath();
@@ -206,5 +262,13 @@
return retval;
}
+ private void setRowExcluded(boolean excluded) {
+ rowExcluded = excluded;
+ row = null;
+ }
+
+ private boolean isRowExcluded() {
+ return rowExcluded;
+ }
}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/StreamingResultsProducer.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/StreamingResultsProducer.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/StreamingResultsProducer.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -35,18 +35,16 @@
import com.metamatrix.connector.xml.XMLConnectorState;
import com.metamatrix.connector.xml.base.ExecutionInfo;
/**
- * Converts a XML InputStream into an List containing results based upon the metadata
- * from the ExecutionInfo. Elements of the List are Lists that represent rows in the
table.
+ * Converts a XML InputStream into an List containing results based upon data
+ * from ExecutionInfo. Elements of the List are Lists that represent rows in the table.
*
*/
public class StreamingResultsProducer {
- ExecutionInfo info;
private StreamingRowCollector collector;
private ElementProcessor elementProcessor;
public StreamingResultsProducer(ExecutionInfo info, XMLConnectorState state) throws
ConnectorException {
- this.info = info;
Map<String, String> namespace = info.getPrefixToNamespacesMap();
XMLReader reader;
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/StreamingRowCollector.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/StreamingRowCollector.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xml/streaming/StreamingRowCollector.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -73,7 +73,7 @@
*/
private void parseRow(Element item) {
Object[] row = elemProcessor.process(item);
- if(!Arrays.asList(row).isEmpty()) {
+ if(null != row && !Arrays.asList(row).isEmpty()) {
this.result.add(row);
}
}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xmlsource/soap/SecurityToken.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xmlsource/soap/SecurityToken.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xmlsource/soap/SecurityToken.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -333,7 +333,7 @@
try {
MessageDigest md = MessageDigest.getInstance("SHA1"); //$NON-NLS-1$
byte[] digest = md.digest(clearText.getBytes());
- sha1Hash = new String(Base64.encode(digest));
+ sha1Hash = Base64.encode(digest);
} catch (Exception e) {
e.printStackTrace();
}
Modified:
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xmlsource/soap/ServiceOperation.java
===================================================================
---
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xmlsource/soap/ServiceOperation.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/main/java/com/metamatrix/connector/xmlsource/soap/ServiceOperation.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -129,20 +129,20 @@
// If query timeout is set use it
if (getQueryTimeout() != -1) {
- this.stub.setTimeout(new Integer(getQueryTimeout()));
+ this.stub.setTimeout(Integer.valueOf(getQueryTimeout()));
}
// check the param count of the submitted operation, in doc-literal
// there should always be only one input
if (isDocLiteral()) {
if (args.length != 1) {
- throw new
ExcutionFailedException(XMLSourcePlugin.Util.getString("wrong_number_params",
new Object[] {new Integer(1), new Integer(args.length)})); //$NON-NLS-1$
+ throw new
ExcutionFailedException(XMLSourcePlugin.Util.getString("wrong_number_params",
new Object[] {Integer.valueOf(1), Integer.valueOf(args.length)})); //$NON-NLS-1$
}
}
else {
int requiredParamCount = this.stub.getOperation().getNumInParams();
if (requiredParamCount != args.length) {
- throw new
ExcutionFailedException(XMLSourcePlugin.Util.getString("wrong_number_params",
new Object[] {new Integer(requiredParamCount), new Integer(args.length)})); //$NON-NLS-1$
+ throw new
ExcutionFailedException(XMLSourcePlugin.Util.getString("wrong_number_params",
new Object[] {Integer.valueOf(requiredParamCount), Integer.valueOf(args.length)}));
//$NON-NLS-1$
}
}
Modified:
trunk/connectors/connector-xml/src/test/java/com/metamatrix/connector/xml/base/TestCriteriaDesc.java
===================================================================
---
trunk/connectors/connector-xml/src/test/java/com/metamatrix/connector/xml/base/TestCriteriaDesc.java 2009-09-10
14:03:21 UTC (rev 1314)
+++
trunk/connectors/connector-xml/src/test/java/com/metamatrix/connector/xml/base/TestCriteriaDesc.java 2009-09-10
15:05:24 UTC (rev 1315)
@@ -507,7 +507,7 @@
public void testGetValues() {
try {
CriteriaDesc desc = createCriteriaDesc(QUERY);
- ArrayList values = desc.getValues();
+ List values = desc.getValues();
assertNotNull("Values list is null", values);
assertEquals(values.get(0), VALUE);
} catch (ConnectorException ce) {