summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src
diff options
context:
space:
mode:
authorlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:13:16 +0000
committerlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:13:16 +0000
commit3ac2d800d840f03618fc364090d786effde84b1f (patch)
treee334754cd5c37e1465230497b48cc79584c1f571 /sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src
parent9bed5ae38c581999db465b42b504026a7097af95 (diff)
Moving 1.x branches
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@835142 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src')
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATA.java64
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATACollection.java28
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementation.java161
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementationFactory.java44
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementationProcessor.java132
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/JDBCHelper.java215
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/JDBCResultSetStreamReader.java53
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/ResultSetXmlNodeImpl.java251
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAImplementationProvider.java98
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAImplementationProviderFactory.java47
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAInvoker.java583
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor19
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory19
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATACollectionTestCaseFIXME.java118
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATAImplementationProcessorTestCase.java133
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATATestCase.java133
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/companyFeed/CompanyFeed.java62
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/companyFeed/CompanyFeedTestCaseFIXME.java51
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/data-feed.composite50
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/data.composite36
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/insert.xml9
-rw-r--r--sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/update.xml7
22 files changed, 2313 insertions, 0 deletions
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATA.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATA.java
new file mode 100644
index 0000000000..3ce96e58da
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATA.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.data;
+
+import javax.xml.stream.XMLStreamReader;
+
+/**
+ * The service interface of a DAS service provided by DAS components.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface DATA {
+
+ /**
+ * Retrieve the Database table contents If a id is given, the results will
+ * be filtered to a matching row
+ *
+ * @param id The PK that identifies the row on the table
+ * @return The row content in XML format
+ */
+ XMLStreamReader get(String id);
+
+ /**
+ * Insert new content in the Database
+ *
+ * @param insertStream The insertion in XML format
+ * @return The number of rows affected
+ */
+ int insert(XMLStreamReader insertStream);
+
+ /**
+ * Update the Database table contents
+ *
+ * @param updateStream The updates in XML format
+ * @return The number of rows affected
+ */
+ int update(XMLStreamReader updateStream);
+
+ /**
+ * Delete the Database table contents If a id is given, only a specific row
+ * will be deleted
+ *
+ * @param id The PK that identifies the row on the table
+ * @return The number of rows affected
+ */
+ int delete(String id);
+
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATACollection.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATACollection.java
new file mode 100644
index 0000000000..1dc5673fe5
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATACollection.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.data;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.data.collection.Collection;
+
+public interface DATACollection extends Collection<String, XMLStreamReader> {
+
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementation.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementation.java
new file mode 100644
index 0000000000..a50ad89b64
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementation.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.data;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.ConstrainingType;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.data.engine.config.ConnectionInfo;
+import org.apache.tuscany.sca.implementation.data.jdbc.JDBCHelper;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+
+
+/**
+ * The model representing a sample DATA implementation in an SCA assembly model.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DATAImplementation implements Implementation {
+ private AssemblyFactory assemblyFactory;
+ private JavaInterfaceFactory javaFactory;
+
+ private ConnectionInfo connectionInfo;
+ private List<Service> services = new ArrayList<Service>();
+
+ /**
+ * Constructs a new DAS implementation.
+ */
+ public DATAImplementation(AssemblyFactory assemblyFactory,
+ JavaInterfaceFactory javaFactory) {
+
+ // DATA implementation provides one service per database table
+ // exposing the DATA interface, and have no references and properties
+ this.assemblyFactory = assemblyFactory;
+ this.javaFactory = javaFactory;
+ }
+
+ private void introspectServices( AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) {
+ Connection connection = null;
+ try {
+ connection = JDBCHelper.getConnection(connectionInfo);
+ DatabaseMetaData databaseMetaData = connection.getMetaData();
+ ResultSet tables = databaseMetaData.getTables(null, null, "%", null);
+ while(tables.next()) {
+ //create the SCA service for the table
+ Service dataService = assemblyFactory.createService();
+ Service dataCollectionService = assemblyFactory.createService();
+
+ dataService.setName(tables.getString(3)+"_DATA");
+ dataCollectionService.setName(tables.getString(3));
+
+ JavaInterface dataInterface;
+ JavaInterface dataCollectionInterface;
+
+ try {
+ dataInterface = javaFactory.createJavaInterface(DATA.class);
+ dataCollectionInterface = javaFactory.createJavaInterface(DATACollection.class);
+ } catch (InvalidInterfaceException e) {
+ throw new IllegalArgumentException(e);
+ }
+ JavaInterfaceContract dataInterfaceContract = javaFactory.createJavaInterfaceContract();
+ JavaInterfaceContract dataCollectionInterfaceContract = javaFactory.createJavaInterfaceContract();
+
+ dataInterfaceContract.setInterface(dataInterface);
+ dataCollectionInterfaceContract.setInterface(dataCollectionInterface);
+
+ dataService.setInterfaceContract(dataInterfaceContract);
+ dataCollectionService.setInterfaceContract(dataCollectionInterfaceContract);
+
+ services.add(dataService);
+ services.add(dataCollectionService);
+
+ }
+ } catch(SQLException e) {
+
+ } finally {
+ JDBCHelper.cleanupResources(connection, null, null);
+ }
+ }
+
+ public ConnectionInfo getConnectionInfo() {
+ return this.connectionInfo;
+ }
+
+ public void setConnectionInfo(ConnectionInfo connectionInfo) {
+ this.connectionInfo = connectionInfo;
+ }
+
+ public ConstrainingType getConstrainingType() {
+ // The sample DATA implementation does not support constrainingTypes
+ return null;
+ }
+
+ public List<Property> getProperties() {
+ // The sample DATA implementation does not support properties
+ return Collections.emptyList();
+ }
+
+ public List<Service> getServices() {
+ if(services == null || services.size() == 0) {
+ introspectServices(assemblyFactory, javaFactory);
+ }
+ return services;
+ }
+
+ public List<Reference> getReferences() {
+ // The sample DATA implementation does not support references
+ return Collections.emptyList();
+ }
+
+ public String getURI() {
+ // The sample DATA implementation does not have a URI
+ return null;
+ }
+
+ public void setConstrainingType(ConstrainingType constrainingType) {
+ // The sample DATA implementation does not support constrainingTypes
+ }
+
+ public void setURI(String uri) {
+ // The sample DATA implementation does not have a URI
+ }
+
+ public boolean isUnresolved() {
+ // The sample DATA implementation is always resolved
+ return false;
+ }
+
+ public void setUnresolved(boolean unresolved) {
+ // The sample DATA implementation is always resolved
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementationFactory.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementationFactory.java
new file mode 100644
index 0000000000..d4cf816dbf
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementationFactory.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.data;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+
+/**
+ * A default factory for the DATA implementation model.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DATAImplementationFactory {
+
+ private AssemblyFactory assemblyFactory;
+ private JavaInterfaceFactory javaFactory;
+
+ public DATAImplementationFactory(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) {
+ this.assemblyFactory = assemblyFactory;
+ this.javaFactory = javaFactory;
+ }
+
+ public DATAImplementation createDASImplementation() {
+ return new DATAImplementation(assemblyFactory, javaFactory);
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementationProcessor.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementationProcessor.java
new file mode 100644
index 0000000000..16c5a370ec
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/DATAImplementationProcessor.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.data;
+
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.xml.Constants;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.service.ContributionReadException;
+import org.apache.tuscany.sca.contribution.service.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.service.ContributionWriteException;
+import org.apache.tuscany.sca.data.engine.ConnectionInfoArtifactProcessor;
+import org.apache.tuscany.sca.data.engine.config.ConnectionInfo;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.monitor.Monitor;
+
+
+/**
+ * Implements a StAX artifact processor for DATA implementations.
+ *
+ * The artifact processor is responsible for processing <implementation.data>
+ * elements in SCA assembly XML composite files and populating the DATA
+ * implementation model, resolving its references to other artifacts in the SCA
+ * contribution, and optionally write the model back to SCA assembly XML.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DATAImplementationProcessor implements StAXArtifactProcessor<DATAImplementation> {
+ protected static final QName IMPLEMENTATION_DATA_XML = new QName(Constants.SCA10_TUSCANY_NS, "implementation.data.xml");
+
+ private DATAImplementationFactory dataFactory;
+ private Monitor monitor;
+ private StAXArtifactProcessor<ConnectionInfo> connectionInfoProcessor;
+
+ public DATAImplementationProcessor(ModelFactoryExtensionPoint modelFactories, Monitor monitor) {
+ AssemblyFactory assemblyFactory = modelFactories.getFactory(AssemblyFactory.class);
+ JavaInterfaceFactory javaFactory = modelFactories.getFactory(JavaInterfaceFactory.class);
+ this.monitor = monitor;
+ this.dataFactory = new DATAImplementationFactory(assemblyFactory, javaFactory);
+ this.connectionInfoProcessor = new ConnectionInfoArtifactProcessor(modelFactories, this.monitor);
+ }
+
+ public QName getArtifactType() {
+ // Returns the qname of the XML element processed by this processor
+ return IMPLEMENTATION_DATA_XML;
+ }
+
+ public Class<DATAImplementation> getModelType() {
+ // Returns the type of model processed by this processor
+ return DATAImplementation.class;
+ }
+
+ /*
+ * <component name="CompanyDataComponent">
+ * <implementation.data.xml>
+ * <connectionInfo>
+ * <connectionProperties
+ * driverClass="org.apache.derby.jdbc.EmbeddedDriver"
+ * databaseURL="jdbc:derby:target/test-classes/dastest; create = true"
+ * loginTimeout="600000"/>
+ * </connectionInfo>
+ * </implementation.data>
+ * </component>
+ */
+ public DATAImplementation read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException {
+ assert IMPLEMENTATION_DATA_XML.equals(reader.getName());
+
+ // Read an <implementation.data.xml> element
+
+ // Create an initialize the DAS implementation model
+ DATAImplementation implementation = dataFactory.createDASImplementation();
+
+ while (true) {
+ int event = reader.next();
+ switch (event) {
+
+ case START_ELEMENT:
+ if (ConnectionInfoArtifactProcessor.CONNECTION_INFO.equals(reader.getName())) {
+
+ // Read connection info
+ ConnectionInfo connectionInfo = (ConnectionInfo) connectionInfoProcessor.read(reader);
+ implementation.setConnectionInfo(connectionInfo);
+ }
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ if (IMPLEMENTATION_DATA_XML.equals(reader.getName())) {
+ return implementation;
+ }
+ break;
+ }
+ }
+
+ }
+
+ public void resolve(DATAImplementation impl, ModelResolver resolver) throws ContributionResolveException {
+ }
+
+ public void write(DATAImplementation implementation, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException {
+ writer.writeStartElement(IMPLEMENTATION_DATA_XML.getNamespaceURI(), IMPLEMENTATION_DATA_XML.getLocalPart());
+
+ if (implementation.getConnectionInfo() != null) {
+ connectionInfoProcessor.write(implementation.getConnectionInfo(), writer);
+ }
+
+ writer.writeEndElement();
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/JDBCHelper.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/JDBCHelper.java
new file mode 100644
index 0000000000..265f250717
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/JDBCHelper.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.data.jdbc;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+import org.apache.tuscany.das.rdb.exception.DataSourceInitializationException;
+import org.apache.tuscany.sca.data.engine.config.ConnectionInfo;
+
+/**
+ * JDBC Helper
+ * - JDBC Connection utility methods
+ * - JDBC Resource cleanup methods
+ *
+ * @version $Rev$ $Date$
+ */
+public class JDBCHelper {
+
+ /**
+ * protected constructor
+ */
+ protected JDBCHelper() {
+
+ }
+
+ /**
+ *
+ * @param connectionInfo
+ * @return
+ */
+ public static Connection getConnection(ConnectionInfo connectionInfo) {
+ if (connectionInfo.getDataSource() == null && connectionInfo.getConnectionProperties() == null) {
+ throw new IllegalArgumentException("Not enough information to create Database Connection.");
+ }
+
+ if(connectionInfo.getDataSource() != null && connectionInfo.getConnectionProperties() != null) {
+ throw new IllegalArgumentException("Use either dataSource or ConnectionProperties. Can't use both !");
+ }
+
+ if(connectionInfo.getDataSource() != null) {
+ return getDataSourceConnection(connectionInfo);
+ } else {
+ return getDriverManagerConnection(connectionInfo);
+ }
+ }
+
+ /**
+ * Initializes a DB connection on a managed environment (e.g inside Tomcat)
+ *
+ * @param connectionInfo
+ * @return
+ */
+ private static Connection getDataSourceConnection(ConnectionInfo connectionInfo) {
+ Connection connection = null;
+
+ InitialContext ctx;
+ try {
+ ctx = new InitialContext();
+ } catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
+ try {
+ DataSource ds = (DataSource) ctx.lookup(connectionInfo.getDataSource());
+ try {
+ connection = ds.getConnection();
+ if (connection == null) {
+ throw new RuntimeException("Could not obtain a Connection from DataSource");
+ }
+ connection.setAutoCommit(false);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ } catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
+
+ return connection;
+ }
+
+ /**
+ * Initialize a DB connection on a J2SE environment
+ * For more info, see http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/drivermanager.html
+ *
+ * @param connectionInfo
+ * @return
+ */
+ private static Connection getDriverManagerConnection(ConnectionInfo connectionInfo) {
+ Connection connection = null;
+
+ if (connectionInfo.getConnectionProperties() == null) {
+ throw new RuntimeException("No existing context and no connection properties");
+ }
+
+ if (connectionInfo.getConnectionProperties().getDriverClass() == null) {
+ throw new RuntimeException("No jdbc driver class specified!");
+ }
+
+ try {
+ Properties p = System.getProperties();
+ p.put("derby.system.home", "target");
+
+ //initialize driver and register it with DriverManager
+ Class.forName(connectionInfo.getConnectionProperties().getDriverClass());
+
+ //prepare to initialize connection
+ String databaseUrl = connectionInfo.getConnectionProperties().getDatabaseURL();
+ String userName = connectionInfo.getConnectionProperties().getUsername();
+ String userPassword = connectionInfo.getConnectionProperties().getPassword();
+ int loginTimeout = connectionInfo.getConnectionProperties().getLoginTimeout();
+
+ DriverManager.setLoginTimeout(loginTimeout);
+ if( (userName == null || userName.length() ==0) && (userPassword == null || userPassword.length()==0) ){
+ //no username or password supplied
+ connection = DriverManager.getConnection(databaseUrl);
+ }else{
+ connection = DriverManager.getConnection(databaseUrl, userName, userPassword);
+ }
+
+ if(connection == null){
+ throw new DataSourceInitializationException("Error initializing connection : null");
+ }
+
+ //FIXME we should make this flexible, we can't autocommit when participating in transactions
+ connection.setAutoCommit(true);
+
+ }catch(ClassNotFoundException cnf){
+ throw new DataSourceInitializationException("JDBC Driver '" + connectionInfo.getConnectionProperties().getDriverClass() + "' not found", cnf);
+ }catch(SQLException sqle){
+ throw new DataSourceInitializationException(sqle.getMessage(), sqle);
+ }
+
+ return connection;
+ }
+
+ /**
+ * Cleanup and close all JDBC resources in the proper order and ignoring erros
+ * @param connection The connection to be closed
+ * @param queryStatement The statement to be closed
+ * @param resultSet The ResultSet to be closed
+ */
+ public static void cleanupResources(Connection connection, PreparedStatement queryStatement, ResultSet resultSet) {
+ cleanupResultSet(resultSet);
+ cleanupPreparedStatement(queryStatement);
+ cleanupConnection(connection);
+ }
+
+ /**
+ * Proper cleanup the ResultSet
+ * @param resultSet
+ */
+ private static void cleanupResultSet(ResultSet resultSet) {
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ // We should log the error. Since we're trying to close, we don't re-throw.
+ }
+ }
+ }
+
+ /**
+ * Proper cleanup the prepared statement
+ * @param queryStatement
+ */
+ private static void cleanupPreparedStatement(PreparedStatement queryStatement) {
+ if (queryStatement != null) {
+ try {
+ queryStatement.close();
+ } catch (SQLException e) {
+ // We should log the error. Since we're trying to close, we don't re-throw.
+ }
+ }
+ }
+
+ /**
+ * proper cleanup the connection
+ * @param connection
+ */
+ private static void cleanupConnection(Connection connection) {
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ // We should log the error. Since we're trying to close, we don't re-throw.
+ }
+ }
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/JDBCResultSetStreamReader.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/JDBCResultSetStreamReader.java
new file mode 100644
index 0000000000..316330243b
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/JDBCResultSetStreamReader.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.data.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.tuscany.sca.databinding.xml.XmlTreeStreamReaderImpl;
+
+/**
+ * JDBCResultSetStreamReader perform streaming of database tables as XML
+ *
+ * @version $Rev$ $Date$
+ */
+public class JDBCResultSetStreamReader extends XmlTreeStreamReaderImpl {
+ private ResultSet resultSet;
+
+ /**
+ * @param root
+ */
+ public JDBCResultSetStreamReader(ResultSet resultSet) {
+ super(new ResultSetXmlNodeImpl(resultSet));
+ this.resultSet = resultSet;
+ }
+
+ @Override
+ public void close() throws XMLStreamException {
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ }
+ }
+}
+
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/ResultSetXmlNodeImpl.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/ResultSetXmlNodeImpl.java
new file mode 100644
index 0000000000..576fe5605d
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/jdbc/ResultSetXmlNodeImpl.java
@@ -0,0 +1,251 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.data.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.databinding.xml.SimpleXmlNodeImpl;
+import org.apache.tuscany.sca.databinding.xml.XmlNode;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ResultSetXmlNodeImpl implements XmlNode {
+ private static final String NS = "";
+ private static final QName RESULT_SET = new QName(NS, "resultSet");
+ private static final QName RECORD = new QName(NS, "record");
+ private static final QName COLUMN = new QName(NS, "column");
+ private static final QName NAME = new QName(NS, "name");
+
+ private ResultSet resultSet;
+ private String[] columnNames;
+
+ /**
+ * @param resultSet
+ */
+ public ResultSetXmlNodeImpl(ResultSet resultSet) {
+ super();
+ this.resultSet = resultSet;
+ try {
+ ResultSetMetaData metaData = resultSet.getMetaData();
+ columnNames = new String[metaData.getColumnCount()];
+ for (int i = 0; i < columnNames.length; i++) {
+ columnNames[i] = metaData.getColumnName(i + 1);
+ }
+ } catch (SQLException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.xml.XmlNode#attributes()
+ */
+ public List<XmlNode> attributes() {
+ return Collections.emptyList();
+ }
+
+ public Type getType() {
+ return Type.ELEMENT;
+ }
+
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.xml.XmlNode#children()
+ */
+ public Iterator<XmlNode> children() {
+ return new ResultSetIteraror();
+ }
+
+ private class ResultSetIteraror implements Iterator<XmlNode> {
+ private Boolean hasNext;
+
+ public ResultSetIteraror() {
+ }
+
+ public boolean hasNext() {
+ try {
+ if (hasNext == null) {
+ hasNext = resultSet.next();
+ }
+ return hasNext;
+ } catch (SQLException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public XmlNode next() {
+ hasNext();
+ hasNext = null;
+ return new RecordXmlNodeImpl();
+ }
+
+ public void remove() {
+ }
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.xml.XmlNode#getName()
+ */
+ public QName getName() {
+ return RESULT_SET;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.xml.XmlNode#getValue()
+ */
+ public String getValue() {
+ return null;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.xml.XmlNode#namespaces()
+ */
+ public Map<String, String> namespaces() {
+ return Collections.emptyMap();
+ }
+
+ private class RecordXmlNodeImpl extends XmlNodeImpl {
+ int index = 0;
+
+ @Override
+ public Iterator<XmlNode> children() {
+ return new Iterator<XmlNode>() {
+
+ public boolean hasNext() {
+ return index < columnNames.length;
+ }
+
+ public XmlNode next() {
+ return new ColumnXmlNodeImpl(index++);
+ }
+
+ public void remove() {
+ }
+
+ };
+ }
+
+ @Override
+ public QName getName() {
+ return RECORD;
+ }
+
+ }
+
+ private class ColumnXmlNodeImpl extends XmlNodeImpl {
+ private int index;
+
+ /**
+ * @param index
+ */
+ public ColumnXmlNodeImpl(int index) {
+ super();
+ this.index = index;
+ }
+
+ @Override
+ public List<XmlNode> attributes() {
+ XmlNode attr = new SimpleXmlNodeImpl(NAME, columnNames[index], XmlNode.Type.ATTRIBUTE);
+ return Arrays.asList(attr);
+ }
+
+ @Override
+ public Iterator<XmlNode> children() {
+ XmlNode[] nodes = {new ValueXmlNodeImpl(index)};
+ return Arrays.asList(nodes).iterator();
+ }
+
+ @Override
+ public QName getName() {
+ return COLUMN;
+ }
+
+ }
+
+ private class ValueXmlNodeImpl extends XmlNodeImpl {
+ private int index;
+
+ /**
+ * @param index
+ */
+ public ValueXmlNodeImpl(int index) {
+ super();
+ this.index = index;
+ }
+
+ @Override
+ public String getValue() {
+ try {
+ return String.valueOf(resultSet.getObject(index + 1));
+ } catch (SQLException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public Type getType() {
+ return Type.CHARACTERS;
+ }
+
+ }
+
+ private static abstract class XmlNodeImpl implements XmlNode {
+
+ public List<XmlNode> attributes() {
+ return Collections.emptyList();
+ }
+
+ public Iterator<XmlNode> children() {
+ return null;
+ }
+
+ public QName getName() {
+ return null;
+ }
+
+ public String getValue() {
+ return null;
+ }
+
+ public boolean isLeaf() {
+ return false;
+ }
+
+ public Map<String, String> namespaces() {
+ return Collections.emptyMap();
+ }
+
+ public Type getType() {
+ return Type.ELEMENT;
+ }
+
+ }
+
+
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAImplementationProvider.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAImplementationProvider.java
new file mode 100644
index 0000000000..bbd963922c
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAImplementationProvider.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.data.provider;
+
+import org.apache.tuscany.sca.implementation.data.DATAImplementation;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+
+/**
+ * DATA Implementation provider
+ *
+ * @version $Rev$ $Date$
+ */
+public class DATAImplementationProvider implements ImplementationProvider {
+ //private RuntimeComponent component;
+ private DATAImplementation implementation;
+
+ /**
+ * Constructs a new DATA implementation.
+ */
+ public DATAImplementationProvider(RuntimeComponent component, DATAImplementation implementation) {
+ //this.component = component;
+ this.implementation = implementation;
+ }
+
+ public Invoker createInvoker(RuntimeComponentService service, Operation operation) {
+ String operationName = operation.getName();
+ String tableName = service.getName();
+
+ String interfaceFullName = operation.getInterface().toString();
+ int index = interfaceFullName.lastIndexOf(".") + 1;
+ String interfaceName = interfaceFullName.substring(index, interfaceFullName.length());
+
+ if (interfaceName.equals("DATACollection")) {
+
+ if (operationName.equals("getAll")) {
+ return new DATAInvoker.GetAllInvoker(operation, implementation.getConnectionInfo(), tableName);
+ } else if (operationName.equals("query")) {
+ return new DATAInvoker.QueryInvoker(operation, implementation.getConnectionInfo(), tableName);
+ } else if (operationName.equals("post")) {
+ return new DATAInvoker.PostInvoker(operation, implementation.getConnectionInfo(), tableName);
+ } else if (operationName.equals("get")) {
+ return new DATAInvoker.GetInvoker(operation, implementation.getConnectionInfo(), tableName);
+ } else if (operationName.equals("put")) {
+ return new DATAInvoker.PutInvoker(operation, implementation.getConnectionInfo(), tableName);
+ } else if (operationName.equals("delete")) {
+ return new DATAInvoker.DeleteInvoker(operation, implementation.getConnectionInfo(), tableName);
+ }
+
+ } else if (interfaceName.equals("DATA")) {
+
+ tableName = tableName.split("_")[0];
+
+ if (operationName.equals("get")) {
+ return new DATAInvoker.GetDATAInvoker(operation, implementation.getConnectionInfo(), tableName);
+ } else if (operationName.equals("insert")) {
+ return new DATAInvoker.InsertDATAInvoker(operation, implementation.getConnectionInfo(), tableName);
+ } else if (operationName.equals("update")) {
+ return new DATAInvoker.UpdateDATAInvoker(operation, implementation.getConnectionInfo(), tableName);
+ } else if (operationName.equals("delete")) {
+ return new DATAInvoker.DeleteDATAInvoker(operation, implementation.getConnectionInfo(), tableName);
+ }
+ }
+
+ return new DATAInvoker(operation, implementation.getConnectionInfo(), tableName);
+ }
+
+ public boolean supportsOneWayInvocation() {
+ return false;
+ }
+
+ public void start() {
+ // System.out.println("Starting " + component.getName());
+ }
+
+ public void stop() {
+ // System.out.println("Stopping " + component.getName());
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAImplementationProviderFactory.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAImplementationProviderFactory.java
new file mode 100644
index 0000000000..e1af9ecd92
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAImplementationProviderFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.data.provider;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.implementation.data.DATAImplementation;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.ImplementationProviderFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * Factory for DATA Implementation Provider
+ *
+ * @version $Rev$ $Date$
+ */
+public class DATAImplementationProviderFactory implements ImplementationProviderFactory<DATAImplementation> {
+
+ /**
+ * Constructs a new DATA implementation.
+ */
+ public DATAImplementationProviderFactory(ExtensionPointRegistry extensionPoints) {
+ }
+
+ public ImplementationProvider createImplementationProvider(RuntimeComponent component, DATAImplementation implementation) {
+ return new DATAImplementationProvider(component, implementation);
+ }
+
+ public Class<DATAImplementation> getModelType() {
+ return DATAImplementation.class;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAInvoker.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAInvoker.java
new file mode 100644
index 0000000000..e74bf4d134
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/java/org/apache/tuscany/sca/implementation/data/provider/DATAInvoker.java
@@ -0,0 +1,583 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.data.provider;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.data.engine.config.ConnectionInfo;
+import org.apache.tuscany.sca.implementation.data.jdbc.JDBCHelper;
+import org.apache.tuscany.sca.implementation.data.jdbc.JDBCResultSetStreamReader;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * Implements a target invoker for DAS component implementations.
+ *
+ * The target invoker is responsible for dispatching invocations to the particular
+ * component implementation logic. The current component implementation will
+ * dispatch calls to the DAS APIs to retrieve the requested data from the back-end store
+ *
+ * @version $Rev$ $Date$
+ */
+public class DATAInvoker implements Invoker {
+
+ protected final Operation operation;
+ protected final ConnectionInfo connectionInfo;
+ protected final String table;
+
+ public DATAInvoker(Operation operation, ConnectionInfo connectionInfo, String table) {
+ this.operation = operation;
+ this.connectionInfo = connectionInfo;
+ this.table = table;
+ }
+
+ public Message invoke(Message msg) {
+ // Shouldn't get here, as the only supported operations
+ // are the ones defined DATA interface and implemented
+ // by specific invoker subclasses
+
+ throw new UnsupportedOperationException(operation.getName());
+ }
+
+ /****************************************************************
+ *
+ * Internal invoker implementations for each supported operation
+ *
+ *****************************************************************/
+ /**
+ * GetAll operation invoker
+ */
+ public static class GetAllInvoker extends DATAInvoker {
+
+ public GetAllInvoker(Operation operation, ConnectionInfo connectionInfo, String table) {
+ super(operation, connectionInfo, table);
+ }
+
+ @Override
+ public Message invoke(Message msg) {
+ return msg;
+ }
+ }
+
+ /**
+ * Query operation invoker
+ */
+ public static class QueryInvoker extends DATAInvoker {
+
+ public QueryInvoker(Operation operation, ConnectionInfo connectionInfo, String table) {
+ super(operation, connectionInfo, table);
+ }
+
+ @Override
+ public Message invoke(Message msg) {
+ return msg;
+ }
+ }
+
+ /**
+ * Post operation invoker
+ */
+ public static class PostInvoker extends DATAInvoker {
+
+ public PostInvoker(Operation operation, ConnectionInfo connectionInfo, String table) {
+ super(operation, connectionInfo, table);
+ }
+
+ @Override
+ public Message invoke(Message msg) {
+
+ StringBuilder sqlInsert = new StringBuilder();
+ XMLStreamReader insertStream = (XMLStreamReader) ((Object[]) msg.getBody())[1];
+
+ if (insertStream == null) {
+ throw new IllegalArgumentException("The XMLStreamReader \"insertStream\" must not be null");
+ }
+
+
+ Connection connection = null;
+ PreparedStatement inStmt = null;
+
+ List<String> colNames = new ArrayList<String>();
+ List<String> values = new ArrayList<String>();
+
+ int result = 0;
+ try {
+
+ connection = JDBCHelper.getConnection(connectionInfo);
+
+ while (insertStream.hasNext()) {
+
+ insertStream.next();
+ if (insertStream.isStartElement()) {
+ if (insertStream.getLocalName().equals("record")) {
+ sqlInsert.append("INSERT INTO " + this.table + " (");
+ } else if (insertStream.getLocalName().equals("column")) {
+ colNames.add(insertStream.getAttributeValue(0));
+ insertStream.next();
+ if (insertStream.isCharacters()) {
+ values.add(insertStream.getText());
+ }
+ }
+ } else if (insertStream.isEndElement() && insertStream.getLocalName().equals("record")) {
+ for (String c : colNames) {
+ sqlInsert.append(" " + c + ",");
+ }
+
+ sqlInsert.deleteCharAt(sqlInsert.length() - 1);
+ sqlInsert.append(" ) VALUES (");
+
+ for (String v : values) {
+ sqlInsert.append(" '" + v + "',");
+ }
+
+ sqlInsert.deleteCharAt(sqlInsert.length() - 1);
+ sqlInsert.append(" )");
+
+ inStmt = connection.prepareStatement(sqlInsert.toString());
+
+ result += inStmt.executeUpdate();
+
+ // Clean up resources
+ inStmt.close();
+ sqlInsert.delete(0, sqlInsert.length());
+ values.clear();
+ colNames.clear();
+ }
+ }
+ } catch (XMLStreamException e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ } catch (SQLException sqle) {
+ sqle.printStackTrace();
+ msg.setFaultBody(new ServiceRuntimeException(sqle.getCause()));
+ } catch (Exception e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ } finally {
+ JDBCHelper.cleanupResources(connection, inStmt, null);
+ }
+
+ msg.setBody(Integer.toString(result));
+ return msg;
+ }
+ }
+
+ /**
+ * Get operation invoker
+ */
+ public static class GetInvoker extends DATAInvoker {
+
+ public GetInvoker(Operation operation, ConnectionInfo connectionInfo, String table) {
+ super(operation, connectionInfo, table);
+ }
+
+ @Override
+ public Message invoke(Message msg) {
+
+ // Get an entry
+ String sqlQuery = null;
+ String id = (String) ((Object[]) msg.getBody())[0];
+
+ if (id == null) {
+ sqlQuery = "SELECT * FROM " + this.table;
+ } else {
+ sqlQuery = "SELECT * FROM " + this.table + " WHERE ID = " + id;
+ }
+
+ Connection connection = null;
+ PreparedStatement queryStatement = null;
+ ResultSet resultSet = null;
+ try {
+ connection = JDBCHelper.getConnection(connectionInfo);
+ queryStatement = connection.prepareStatement(sqlQuery);
+ resultSet = queryStatement.executeQuery();
+
+
+ } catch (SQLException sqle) {
+ msg.setFaultBody(new ServiceRuntimeException(sqle.getCause()));
+ JDBCHelper.cleanupResources(connection, queryStatement, resultSet);
+ } catch (Exception e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ JDBCHelper.cleanupResources(connection, queryStatement, resultSet);
+ } finally {
+ //default we leave the connection open to pass to the JDBCStreamReader
+ }
+
+ msg.setBody(new JDBCResultSetStreamReader(resultSet));
+ return msg;
+ }
+ }
+
+ /**
+ * Put operation invoker
+ */
+ public static class PutInvoker extends DATAInvoker {
+
+ public PutInvoker(Operation operation, ConnectionInfo connectionInfo, String table) {
+ super(operation, connectionInfo, table);
+ }
+
+ @Override
+ public Message invoke(Message msg) {
+
+ XMLStreamReader updateStream = (XMLStreamReader) ((Object[]) msg.getBody())[1];
+
+ if (updateStream == null) {
+ throw new IllegalArgumentException("The XMLStreamReader \"updateStream\" must not be null");
+ }
+
+ Connection connection = null;
+ PreparedStatement upStmt = null;
+
+ String id = null;
+ String columnName = null;
+ String newValue = null;
+ int result = 0;
+
+ try {
+ connection = JDBCHelper.getConnection(connectionInfo);
+ while (updateStream.hasNext()) {
+ updateStream.next();
+
+ if (updateStream.isStartElement() && updateStream.getLocalName().equals("column")) {
+ columnName = updateStream.getAttributeValue(0);
+ updateStream.next();
+ if (updateStream.isCharacters()) {
+ if (columnName.equals("ID")) {
+ id = updateStream.getText();
+ } else {
+ newValue = updateStream.getText();
+
+ upStmt = connection.prepareStatement("UPDATE " + this.table + " SET " + columnName + " = '" + newValue + "' WHERE ID = " + id);
+
+ result += upStmt.executeUpdate();
+ upStmt.close();
+ }
+ }
+ }
+ }
+ } catch (XMLStreamException e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ } catch (SQLException sqle) {
+ sqle.printStackTrace();
+ msg.setFaultBody(new ServiceRuntimeException(sqle.getCause()));
+ } catch (Exception e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ } finally {
+ JDBCHelper.cleanupResources(connection, upStmt, null);
+ }
+
+ msg.setBody(result);
+ return msg;
+ }
+ }
+
+ /**
+ * Delete operation invoker
+ */
+ public static class DeleteInvoker extends DATAInvoker {
+
+ public DeleteInvoker(Operation operation, ConnectionInfo connectionInfo, String table) {
+ super(operation, connectionInfo, table);
+ }
+
+ @Override
+ public Message invoke(Message msg) {
+
+ // Get an entry
+ String sqlDelete = null;
+ String id = (String) ((Object[]) msg.getBody())[0];
+
+ if (id == null) {
+ sqlDelete = "DELETE FROM " + this.table;
+ } else {
+ sqlDelete = "DELETE FROM " + this.table + " WHERE ID = " + id;
+ }
+
+ Connection connection = null;
+ PreparedStatement deleteStatement = null;
+ int result = -1;
+
+ try {
+ connection = JDBCHelper.getConnection(connectionInfo);
+ deleteStatement = connection.prepareStatement(sqlDelete);
+ result = deleteStatement.executeUpdate();
+
+ } catch (SQLException sqle) {
+ msg.setFaultBody(new ServiceRuntimeException(sqle.getCause()));
+ } catch (Exception e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ } finally {
+ JDBCHelper.cleanupResources(connection, deleteStatement, null);
+ }
+
+ msg.setBody(result);
+ return msg;
+ }
+ }
+ /**
+ * Get operation invoker
+ *
+ * @version $Rev$ $Date$
+ */
+ public static class GetDATAInvoker extends DATAInvoker {
+
+ public GetDATAInvoker(Operation operation, ConnectionInfo connectionInfo, String table) {
+ super(operation, connectionInfo, table);
+ }
+
+ @Override
+ public Message invoke(Message msg) {
+
+ // Get an entry
+ String sqlQuery = null;
+ String id = (String) ((Object[]) msg.getBody())[0];
+
+ if (id == null) {
+ sqlQuery = "SELECT * FROM " + this.table;
+ } else {
+ sqlQuery = "SELECT * FROM " + this.table + " WHERE ID = " + id;
+ }
+
+ Connection connection = null;
+ PreparedStatement queryStatement = null;
+ ResultSet resultSet = null;
+ try {
+ connection = JDBCHelper.getConnection(connectionInfo);
+ queryStatement = connection.prepareStatement(sqlQuery);
+ resultSet = queryStatement.executeQuery();
+
+
+ } catch (SQLException sqle) {
+ msg.setFaultBody(new ServiceRuntimeException(sqle.getCause()));
+ JDBCHelper.cleanupResources(connection, queryStatement, resultSet);
+ } catch (Exception e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ JDBCHelper.cleanupResources(connection, queryStatement, resultSet);
+ } finally {
+ //default we leave the connection open to pass to the JDBCStreamReader
+ }
+
+ msg.setBody(new JDBCResultSetStreamReader(resultSet));
+ return msg;
+ }
+ }
+
+ /**
+ * Insert operation invoker
+ */
+ public static class InsertDATAInvoker extends DATAInvoker {
+
+ public InsertDATAInvoker(Operation operation,
+ ConnectionInfo connectionInfo, String table) {
+ super(operation, connectionInfo, table);
+ }
+
+ @Override
+ public Message invoke(Message msg) throws IllegalArgumentException {
+ StringBuilder sqlInsert = new StringBuilder();
+ XMLStreamReader insertStream = (XMLStreamReader) ((Object[]) msg.getBody())[0];
+
+ if (insertStream == null) {
+ throw new IllegalArgumentException("The XMLStreamReader \"insertStream\" must not be null");
+ }
+
+
+ Connection connection = null;
+ PreparedStatement inStmt = null;
+
+ List<String> colNames = new ArrayList<String>();
+ List<String> values = new ArrayList<String>();
+
+ int result = 0;
+ try {
+
+ connection = JDBCHelper.getConnection(connectionInfo);
+
+ while (insertStream.hasNext()) {
+
+ insertStream.next();
+ if (insertStream.isStartElement()) {
+ if (insertStream.getLocalName().equals("record")) {
+ sqlInsert.append("INSERT INTO " + this.table + " (");
+ } else if (insertStream.getLocalName().equals("column")) {
+ colNames.add(insertStream.getAttributeValue(0));
+ insertStream.next();
+ if (insertStream.isCharacters()) {
+ values.add(insertStream.getText());
+ }
+ }
+ } else if (insertStream.isEndElement() && insertStream.getLocalName().equals("record")) {
+ for (String c : colNames) {
+ sqlInsert.append(" " + c + ",");
+ }
+
+ sqlInsert.deleteCharAt(sqlInsert.length() - 1);
+ sqlInsert.append(" ) VALUES (");
+
+ for (String v : values) {
+ sqlInsert.append(" '" + v + "',");
+ }
+
+ sqlInsert.deleteCharAt(sqlInsert.length() - 1);
+ sqlInsert.append(" )");
+
+ inStmt = connection.prepareStatement(sqlInsert.toString());
+ result += inStmt.executeUpdate();
+
+ // Clean up resources
+ inStmt.close();
+ sqlInsert.delete(0, sqlInsert.length());
+ values.clear();
+ colNames.clear();
+ }
+ }
+ } catch (XMLStreamException e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ } catch (SQLException sqle) {
+ sqle.printStackTrace();
+ msg.setFaultBody(new ServiceRuntimeException(sqle.getCause()));
+ } catch (Exception e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ } finally {
+ JDBCHelper.cleanupResources(connection, inStmt, null);
+ }
+
+ msg.setBody(result);
+ return msg;
+ }
+ }
+
+ /**
+ * Update operation invoker
+ */
+ public static class UpdateDATAInvoker extends DATAInvoker {
+
+ public UpdateDATAInvoker(Operation operation,
+ ConnectionInfo connectionInfo, String table) {
+ super(operation, connectionInfo, table);
+ }
+
+ @Override
+ public Message invoke(Message msg) throws IllegalArgumentException {
+
+ XMLStreamReader updateStream = (XMLStreamReader) ((Object[]) msg.getBody())[0];
+
+ if (updateStream == null) {
+ throw new IllegalArgumentException("The XMLStreamReader \"updateStream\" must not be null");
+ }
+
+ Connection connection = null;
+ PreparedStatement upStmt = null;
+
+ String id = null;
+ String columnName = null;
+ String newValue = null;
+ int result = 0;
+
+ try {
+ connection = JDBCHelper.getConnection(connectionInfo);
+ while (updateStream.hasNext()) {
+ updateStream.next();
+
+ if (updateStream.isStartElement() && updateStream.getLocalName().equals("column")) {
+ columnName = updateStream.getAttributeValue(0);
+ updateStream.next();
+ if (updateStream.isCharacters()) {
+ if (columnName.equals("ID")) {
+ id = updateStream.getText();
+ } else {
+ newValue = updateStream.getText();
+
+ upStmt = connection.prepareStatement("UPDATE " + this.table + " SET " + columnName + " = '" + newValue + "' WHERE ID = " + id);
+
+ result += upStmt.executeUpdate();
+ upStmt.close();
+ }
+ }
+ }
+ }
+ } catch (XMLStreamException e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ } catch (SQLException sqle) {
+ sqle.printStackTrace();
+ msg.setFaultBody(new ServiceRuntimeException(sqle.getCause()));
+ } catch (Exception e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ } finally {
+ JDBCHelper.cleanupResources(connection, upStmt, null);
+ }
+
+ msg.setBody(result);
+ return msg;
+ }
+ }
+
+ /**
+ * Delete operation invoker
+ */
+ public static class DeleteDATAInvoker extends DATAInvoker {
+
+ public DeleteDATAInvoker(Operation operation, ConnectionInfo connectionInfo, String table) {
+ super(operation, connectionInfo, table);
+ }
+
+ @Override
+ public Message invoke(Message msg) {
+
+ // Get an entry
+ String sqlDelete = null;
+ String id = (String) ((Object[]) msg.getBody())[0];
+
+ if (id == null) {
+ sqlDelete = "DELETE FROM " + this.table;
+ } else {
+ sqlDelete = "DELETE FROM " + this.table + " WHERE ID = " + id;
+ }
+
+ Connection connection = null;
+ PreparedStatement deleteStatement = null;
+ int result = -1;
+
+ try {
+ connection = JDBCHelper.getConnection(connectionInfo);
+ deleteStatement = connection.prepareStatement(sqlDelete);
+ result = deleteStatement.executeUpdate();
+
+ } catch (SQLException sqle) {
+ msg.setFaultBody(new ServiceRuntimeException(sqle.getCause()));
+ } catch (Exception e) {
+ msg.setFaultBody(new ServiceRuntimeException(e));
+ } finally {
+ JDBCHelper.cleanupResources(connection, deleteStatement, null);
+ }
+
+ msg.setBody(result);
+ return msg;
+ }
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
new file mode 100644
index 0000000000..5cd3334e3f
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Implementation class for the artifact processor extension
+org.apache.tuscany.sca.implementation.data.DATAImplementationProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.0#implementation.data.xml,model=org.apache.tuscany.sca.implementation.data.DATAImplementation
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory
new file mode 100644
index 0000000000..e20f1a6379
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Implementation class for the implementation extension
+org.apache.tuscany.sca.implementation.data.provider.DATAImplementationProviderFactory;model=org.apache.tuscany.sca.implementation.data.DATAImplementation
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATACollectionTestCaseFIXME.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATACollectionTestCaseFIXME.java
new file mode 100644
index 0000000000..458025dd66
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATACollectionTestCaseFIXME.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.data;
+
+import java.io.FileInputStream;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+import junit.framework.TestCase;
+import org.apache.tuscany.sca.databinding.xml.XMLStreamReader2String;
+import org.apache.tuscany.sca.host.embedded.SCADomain;
+import org.apache.tuscany.sca.implementation.data.DATACollection;
+
+public class DATACollectionTestCaseFIXME extends TestCase {
+
+ private SCADomain scaDomain;
+ private DATACollection dataService;
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ protected void setUp() throws Exception {
+ scaDomain = SCADomain.newInstance("data.composite");
+ dataService = scaDomain.getService(DATACollection.class, "DataComponent/COMPANY");
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ scaDomain.close();
+ }
+
+ public void testInsert() throws Exception {
+ System.out.println(">testInsert");
+
+ //Read and process the XML file
+ FileInputStream fileInputStream = new FileInputStream("src/test/resources/insert.xml");
+ XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream);
+
+ String result = dataService.post(null, reader);
+ assertEquals(result, "2");
+
+ System.out.println("Number of rows inserted: " + result);
+
+ reader.close();
+ }
+
+ public void testGet() throws Exception {
+
+ System.out.println(">testGet");
+
+ XMLStreamReader reader = dataService.get(null);
+ assertNotNull(reader);
+ String xml = new XMLStreamReader2String().transform(reader, null);
+ System.out.println(xml);
+ reader.close();
+ }
+
+ public void testUpdate() throws Exception {
+
+ System.out.println(">testUpdate");
+
+ //Read and process the XML file
+ FileInputStream fileInputStream = new FileInputStream("src/test/resources/update.xml");
+ XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream);
+
+ dataService.put(null,reader);
+
+ reader.close();
+ }
+
+ public void testGetByID() throws Exception {
+ System.out.println(">testGetByID");
+
+ Integer companyID = new Integer(4);
+
+ XMLStreamReader reader = dataService.get(companyID.toString());
+ assertNotNull(reader);
+ String xml = new XMLStreamReader2String().transform(reader, null);
+ System.out.println(xml);
+ reader.close();
+ }
+
+ public void testDeleteByID() throws Exception {
+ System.out.println(">testDeleteByID");
+
+ Integer companyID = new Integer(4);
+ dataService.delete(companyID.toString());
+ }
+
+ public void testDelete() throws Exception {
+ System.out.println(">testDelete");
+
+ dataService.delete(null);
+
+ System.out.println("recreating database...");
+ //Helper.createDB();
+ System.out.println("done!");
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATAImplementationProcessorTestCase.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATAImplementationProcessorTestCase.java
new file mode 100644
index 0000000000..dcf87d8c68
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATAImplementationProcessorTestCase.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.data;
+
+import java.io.StringReader;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.SCABindingFactory;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilder;
+import org.apache.tuscany.sca.assembly.builder.impl.CompositeBuilderImpl;
+import org.apache.tuscany.sca.assembly.xml.Constants;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.DefaultStAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.data.engine.config.ConnectionInfo;
+import org.apache.tuscany.sca.data.engine.config.ConnectionProperties;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.impl.InterfaceContractMapperImpl;
+import org.apache.tuscany.sca.policy.IntentAttachPointTypeFactory;
+
+/**
+ * @version $Rev: 538445 $ $Date: 2007-05-15 23:20:37 -0700 (Tue, 15 May 2007) $
+ */
+public class DATAImplementationProcessorTestCase extends TestCase {
+
+ protected static final QName IMPLEMENTATION_DATA = new QName(Constants.SCA10_TUSCANY_NS, "implementation.data.xml");
+
+ private static final String COMPOSITE_USING_DATASOURCE =
+ "<?xml version=\"1.0\" encoding=\"ASCII\"?>"
+ + "<composite xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:tuscany=\"http://tuscany.apache.org/xmlns/sca/1.0\" targetNamespace=\"http://data\" name=\"data\">"
+ + " <component name=\"DataComponent\">"
+ + " <tuscany:implementation.data.xml>"
+ + " <tuscany:connectionInfo datasource=\"dataSource\"/>"
+ + " </tuscany:implementation.data.xml>"
+ + " </component>"
+ + "</composite>";
+
+ private static final String COMPOSITE_USING_CONNECTION_PROPERTIES =
+ "<?xml version=\"1.0\" encoding=\"ASCII\"?>"
+ + "<composite xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:tuscany=\"http://tuscany.apache.org/xmlns/sca/1.0\" targetNamespace=\"http://data\" name=\"data\">"
+ + " <component name=\"DataComponent\">"
+ + " <tuscany:implementation.data.xml>"
+ + " <tuscany:connectionInfo>"
+ + " <tuscany:connectionProperties"
+ + " driverClass=\"driverClass\""
+ + " databaseURL=\"databaseURL\""
+ + " loginTimeout=\"1\"/>"
+ + " </tuscany:connectionInfo>"
+ + " </tuscany:implementation.data.xml>"
+ + " </component>"
+ + "</composite>";
+
+ private XMLInputFactory inputFactory;
+ private StAXArtifactProcessor<Object> staxProcessor;
+ private CompositeBuilder compositeBuilder;
+
+ @Override
+ protected void setUp() throws Exception {
+ DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry();
+ inputFactory = XMLInputFactory.newInstance();
+ StAXArtifactProcessorExtensionPoint staxProcessors = new DefaultStAXArtifactProcessorExtensionPoint(extensionPoints);
+ staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null, null);
+
+ ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class);
+ AssemblyFactory assemblyFactory = modelFactories.getFactory(AssemblyFactory.class);
+ SCABindingFactory scaBindingFactory = modelFactories.getFactory(SCABindingFactory.class);
+ UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class);
+ InterfaceContractMapper mapper = utilities.getUtility(InterfaceContractMapper.class);
+ IntentAttachPointTypeFactory attachPointTypeFactory = modelFactories.getFactory(IntentAttachPointTypeFactory.class);
+ compositeBuilder = new CompositeBuilderImpl(assemblyFactory, scaBindingFactory, attachPointTypeFactory, mapper, null);
+ }
+
+ public void testLoadCompositeUsingDatasource() throws Exception {
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(COMPOSITE_USING_DATASOURCE));
+
+ Composite composite = (Composite)staxProcessor.read(reader);
+ DATAImplementation implementation = (DATAImplementation)composite.getComponents().get(0).getImplementation();
+ assertNotNull(implementation);
+
+ ConnectionInfo connInfo = implementation.getConnectionInfo();
+ assertNotNull(connInfo);
+ assertEquals("dataSource", connInfo.getDataSource());
+
+ ConnectionProperties connProperties = connInfo.getConnectionProperties();
+ assertNull(connProperties);
+ }
+
+ public void testLoadCompositeUsingConnectionProperties() throws Exception {
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(COMPOSITE_USING_CONNECTION_PROPERTIES));
+
+ Composite composite = (Composite)staxProcessor.read(reader);
+ DATAImplementation implementation = (DATAImplementation)composite.getComponents().get(0).getImplementation();
+ assertNotNull(implementation);
+
+ ConnectionInfo connInfo = implementation.getConnectionInfo();
+ assertNotNull(connInfo);
+ assertNull("dataSource", connInfo.getDataSource());
+
+ ConnectionProperties connProperties = connInfo.getConnectionProperties();
+ assertNotNull(connProperties);
+ assertEquals("driverClass",connProperties.getDriverClass());
+ assertEquals("databaseURL",connProperties.getDatabaseURL());
+ assertEquals(1,connProperties.getLoginTimeout().intValue());
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATATestCase.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATATestCase.java
new file mode 100644
index 0000000000..4010cb63d3
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/DATATestCase.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.data;
+
+import java.io.FileInputStream;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.databinding.xml.XMLStreamReader2String;
+import org.apache.tuscany.sca.host.embedded.SCADomain;
+import org.apache.tuscany.sca.implementation.data.DATA;
+
+/**
+ * Tests the DAS service
+ *
+ * @version $Rev$ $Date$
+ */
+public class DATATestCase extends TestCase {
+ private SCADomain scaDomain;
+ private DATA dataService;
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ protected void setUp() throws Exception {
+ scaDomain = SCADomain.newInstance("data.composite");
+ dataService = scaDomain.getService(DATA.class, "DataComponent/COMPANY_DATA");
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ scaDomain.close();
+ }
+
+ public void testInsert() throws Exception {
+ System.out.println(">testInsert");
+
+ //Read and process the XML file
+ FileInputStream fileInputStream = new FileInputStream("src/test/resources/insert.xml");
+ XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream);
+
+ int result = dataService.insert(reader);
+ assertEquals(result,2);
+
+ System.out.println("Number of rows inserted: "+result);
+
+ reader.close();
+ }
+
+ public void testGet() throws Exception {
+
+ System.out.println(">testGet");
+
+ XMLStreamReader reader = dataService.get(null);
+ assertNotNull(reader);
+ String xml = new XMLStreamReader2String().transform(reader, null);
+ System.out.println(xml);
+ reader.close();
+ }
+
+ public void testUpdate() throws Exception {
+
+ System.out.println(">testUpdate");
+
+ //Read and process the XML file
+ FileInputStream fileInputStream = new FileInputStream("src/test/resources/update.xml");
+ XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(fileInputStream);
+
+ int result = dataService.update(reader);
+ assertEquals(result,1);
+ System.out.println("Number of rows affected: "+result);
+
+ reader.close();
+ }
+
+ public void testGetByID() throws Exception {
+ System.out.println(">testGetByID");
+
+ Integer companyID = new Integer(4);
+
+ XMLStreamReader reader = dataService.get(companyID.toString());
+ assertNotNull(reader);
+ String xml = new XMLStreamReader2String().transform(reader, null);
+ System.out.println(xml);
+ reader.close();
+ }
+
+ public void testDeleteByID() throws Exception {
+ System.out.println(">testDeleteByID");
+
+ Integer companyID = new Integer(4);
+ int result = dataService.delete(companyID.toString());
+ assertEquals(result,1);
+ System.out.println("Number of rows deleted: "+result);
+ }
+
+ public void testDelete() throws Exception {
+ System.out.println(">testDelete");
+
+ int result = dataService.delete(null);
+ assertEquals(result,4);
+ System.out.println("Number of rows deleted: "+result);
+
+ System.out.println("recreating database...");
+ //Helper.createDB();
+ System.out.println("done!");
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/companyFeed/CompanyFeed.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/companyFeed/CompanyFeed.java
new file mode 100644
index 0000000000..7f0707c0bc
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/companyFeed/CompanyFeed.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.data.companyFeed;
+
+import org.apache.tuscany.sca.data.collection.Collection;
+import org.apache.tuscany.sca.data.collection.Entry;
+import org.apache.tuscany.sca.data.collection.NotFoundException;
+import org.apache.tuscany.sca.implementation.data.DATA;
+import org.osoa.sca.annotations.Reference;
+
+import commonj.sdo.DataObject;
+
+public class CompanyFeed implements Collection<String, DataObject> {
+
+ @Reference
+ protected DATA dataService;
+
+ public Entry<String, DataObject>[] getAll() {
+ return null;
+ }
+
+ public DataObject get(String id) throws NotFoundException{
+
+ DataObject data = null;//dataService.get(id);
+ if(data == null) {
+ throw new NotFoundException();
+ } else {
+ return data;
+ }
+ }
+
+ public void delete(String id) throws NotFoundException {
+ }
+
+ public String post(String key, DataObject item) {
+ return null;
+ }
+
+ public void put(String key, DataObject item) throws NotFoundException {
+ }
+
+ public Entry<String, DataObject>[] query(String queryString) {
+ return null;
+ }
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/companyFeed/CompanyFeedTestCaseFIXME.java b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/companyFeed/CompanyFeedTestCaseFIXME.java
new file mode 100644
index 0000000000..b72ff89e3b
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/java/org/apache/tuscany/sca/implementation/data/companyFeed/CompanyFeedTestCaseFIXME.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.implementation.data.companyFeed;
+
+import java.io.IOException;
+import java.net.Socket;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.host.embedded.SCADomain;
+
+/**
+ * @version $Rev: 543175 $ $Date: 2007-05-31 09:09:12 -0700 (Thu, 31 May 2007) $
+ */
+public class CompanyFeedTestCaseFIXME extends TestCase {
+ private SCADomain scaDomain;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ scaDomain = SCADomain.newInstance("data-feed.composite");
+ //System.in.read();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ scaDomain.close();
+ }
+
+ public void testPing() throws IOException {
+ new Socket("127.0.0.1", 8085);
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/data-feed.composite b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/data-feed.composite
new file mode 100644
index 0000000000..40c755b134
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/data-feed.composite
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
+ targetNamespace="http://data"
+ name="data-feed">
+
+
+ <service name="CompanyFeed" promote="CompanyFeedComponent">
+ <tuscany:binding.atom uri="http://localhost:8085/comnpanyfeed/*"/>
+ </service>
+
+ <component name="CompanyFeedComponent">
+ <implementation.java class="org.apache.tuscany.sca.implementation.data.companyFeed.CompanyFeed"/>
+ <reference name="dataService" target="CompanyDataComponent"/>
+ </component>
+
+ <!-- service name="CompanyDataServiceComponent" promote="CompanyDataComponent">
+ <binding.atom uri="http://localhost:8085/comnpanyfeed/"/>
+ </service -->
+
+ <component name="CompanyDataComponent">
+ <tuscany:implementation.data.xml table="company">
+ <tuscany:connectionInfo>
+ <tuscany:connectionProperties
+ driverClass="org.apache.derby.jdbc.EmbeddedDriver"
+ databaseURL="jdbc:derby:target/test-classes/company; create = true"
+ loginTimeout="600000"/>
+ </tuscany:connectionInfo>
+ </tuscany:implementation.data.xml>
+ </component>
+
+</composite>
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/data.composite b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/data.composite
new file mode 100644
index 0000000000..f30b15e34c
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/data.composite
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
+ targetNamespace="http://data"
+ name="data">
+
+ <component name="DataComponent">
+ <tuscany:implementation.data.xml>
+ <tuscany:connectionInfo>
+ <tuscany:connectionProperties
+ driverClass="org.apache.derby.jdbc.EmbeddedDriver"
+ databaseURL="jdbc:derby:target/test-classes/company; create = true"
+ loginTimeout="600000"/>
+ </tuscany:connectionInfo>
+ </tuscany:implementation.data.xml>
+ </component>
+
+</composite>
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/insert.xml b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/insert.xml
new file mode 100644
index 0000000000..c0a5ada4bf
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/insert.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resultSet>
+ <record>
+ <column name="NAME">New Coorporation I</column>
+ </record>
+ <record>
+ <column name="NAME">New Coorporation II</column>
+ </record>
+</resultSet>
diff --git a/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/update.xml b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/update.xml
new file mode 100644
index 0000000000..c6cef75274
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-20080910/modules/implementation-data-xml/src/test/resources/update.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<result_set>
+ <record>
+ <column name="ID">4</column>
+ <column name="NAME">Update Coorporation</column>
+ </record>
+</result_set>